lookbook 发表于 2019-7-3 00:39:30

一个关于无类型指针的问题

书上看到class(*)这么一个东西,
于是自己像下面这样使用


...

type(balabala) :: father

class(*),allocatable :: temp

allocate(temp,source=father)

...

但发觉死活不行,无论gfortran还是pgi

后来才领悟,原来class(*)类型的变量/指针只能在select type内使用。

突然觉得这东西局限很大啊,在此记录一笔,也供大家参考。


liudy02 发表于 2019-7-3 07:31:09

我还没注意还有这个呢
你是原本以为可以有C里边void *那种神奇的功能?

lookbook 发表于 2019-7-3 12:53:44

liudy02 发表于 2019-7-3 07:31
我还没注意还有这个呢
你是原本以为可以有C里边void *那种神奇的功能?

是的,不过在select type内部可以。
轻量级的代码或许能行

liudy02 发表于 2019-7-3 13:40:34

lookbook 发表于 2019-7-3 12:53
是的,不过在select type内部可以。
轻量级的代码或许能行

不懂,我现在渐渐觉得fortran确实没啥不可替代性了
似乎一般的数学库也都有C语言版了
甚至连python里的numpy,scipy之类的库都做的很好了
fortran的oop做的那么烂,语言设计也确实不太好,感觉自己主动去用没啥必要了
也就是需要用别人的代码时需要搞清楚一些看不懂的问题就ok了

lookbook 发表于 2019-7-3 16:22:06

liudy02 发表于 2019-7-3 13:40
不懂,我现在渐渐觉得fortran确实没啥不可替代性了
似乎一般的数学库也都有C语言版了
甚至连python里的nu ...

你会多少种语言了?

liudy02 发表于 2019-7-3 17:02:32

lookbook 发表于 2019-7-3 16:22
你会多少种语言了?

老实说,一种也谈不上"会"啊
三四种都只是略知一点皮毛而已
但是fortran确实曾经用过很久,也花过不少功夫学习
确实发现曾经的优势都在慢慢消失,劣势却没有什么改善

fcode 发表于 2019-7-3 18:10:28

class(*) 有挺多妙用的呀。
对于一些函数里不对输入数据进行操作,直接传递出去的,都可以用它。

我写过一个转换大小端的程序,用了 class(*) 之后,我就不需要为 real4 , real8 , real16 , integer2, integer4 , integer8 分别写一次了。

program main
implicit none
Integer :: a
Real :: b
a = 3
b = 1.0
write(*,'("0x",z8.8)') a
call CnvrtEndian( a , 4 )
write(*,'("0x",z8.8)') a
write(*,'("0x",z8.8)') b
call CnvrtEndian( b , 4 )
write(*,'("0x",z8.8)') b
contains

Subroutine CnvrtEndian( byteIn , nByte )
    use , intrinsic :: ISO_C_Binding
    class(*) , target , Intent(INOUT) :: byteIn
    integer, Intent(IN)             :: nByte
    character , pointer :: p(:)
    call c_f_pointer( c_loc(byteIn) , p , )
    p = p(nByte:1:-1)
End Subroutine CnvrtEndian

end program main

liudy02 发表于 2019-7-3 19:18:30

fcode 发表于 2019-7-3 18:10
class(*) 有挺多妙用的呀。
对于一些函数里不对输入数据进行操作,直接传递出去的,都可以用它。


将一个数按位倒置,这个看起来不像是fortran这门语言设计的需求啊……
fortran设计的理念似乎一直是不要让用户去关心内部是怎么存储数据的
虽然后来引入了位操作函数,不也是不管实际存储情况,只是假设按固定位顺序存储设计的么?

liudy02 发表于 2019-7-3 19:29:26

fcode 发表于 2019-7-3 18:10
class(*) 有挺多妙用的呀。
对于一些函数里不对输入数据进行操作,直接传递出去的,都可以用它。



从你这个例子里,学到一点
就是想利用这一点的话,相当于一定程度上可以使得子进程的哑元确实就是 void *的指针
只是实际要运用的话,还是受制于子进程内部能实现什么样的无关类型的通用代码
感觉这个如果和自定义算符以及通用函数名确实还是有很实际的运用的
一定程度上可以实现类似模板,或者多态的功能

lookbook 发表于 2019-7-3 22:39:48

fcode 发表于 2019-7-3 18:10
class(*) 有挺多妙用的呀。
对于一些函数里不对输入数据进行操作,直接传递出去的,都可以用它。



谢谢绝地,
但这个代码在gfortran下测试并不成功,c_f_pointer不接受多态的指针,pgi是可以的,我猜ivf也是可以的吧。
还有请问为什么要用iso_c_binding?这段没有太明白。

后来我记起来了,fortran用父类指针也能实现一定的多态性质,只要顶层的接口设计好。
页: [1] 2
查看完整版本: 一个关于无类型指针的问题