Fortran Coder

查看: 18940|回复: 18
打印 上一主题 下一主题

[面向对象] 一个关于无类型指针的问题

[复制链接]

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
跳转到指定楼层
楼主
发表于 2019-7-3 00:39:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
书上看到class(*)这么一个东西,
于是自己像下面这样使用


...

type(balabala) :: father

class(*),allocatable :: temp

allocate(temp,source=father)

...

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

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

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


分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
沙发
发表于 2019-7-3 07:31:09 | 只看该作者
我还没注意还有这个呢
你是原本以为可以有C里边void *那种神奇的功能?

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
板凳
 楼主| 发表于 2019-7-3 12:53:44 | 只看该作者
liudy02 发表于 2019-7-3 07:31
我还没注意还有这个呢
你是原本以为可以有C里边void *那种神奇的功能?

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

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
地板
发表于 2019-7-3 13:40:34 | 只看该作者
lookbook 发表于 2019-7-3 12:53
是的,不过在select type内部可以。
轻量级的代码或许能行

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

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
5#
 楼主| 发表于 2019-7-3 16:22:06 | 只看该作者
liudy02 发表于 2019-7-3 13:40
不懂,我现在渐渐觉得fortran确实没啥不可替代性了
似乎一般的数学库也都有C语言版了
甚至连python里的nu ...

你会多少种语言了?

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
6#
发表于 2019-7-3 17:02:32 | 只看该作者
lookbook 发表于 2019-7-3 16:22
你会多少种语言了?

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

1962

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1353 元
贡献
572 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

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

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

[Fortran] 纯文本查看 复制代码
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 , [nByte] )
    p = p(nByte:1:-1)
  End Subroutine CnvrtEndian
  
end program main

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
8#
发表于 2019-7-3 19:18:30 | 只看该作者
fcode 发表于 2019-7-3 18:10
class(*) 有挺多妙用的呀。
对于一些函数里不对输入数据进行操作,直接传递出去的,都可以用它。

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

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
9#
发表于 2019-7-3 19:29:26 | 只看该作者
fcode 发表于 2019-7-3 18:10
class(*) 有挺多妙用的呀。
对于一些函数里不对输入数据进行操作,直接传递出去的,都可以用它。

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

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
10#
 楼主| 发表于 2019-7-3 22:39:48 | 只看该作者
fcode 发表于 2019-7-3 18:10
class(*) 有挺多妙用的呀。
对于一些函数里不对输入数据进行操作,直接传递出去的,都可以用它。

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

后来我记起来了,fortran用父类指针也能实现一定的多态性质,只要顶层的接口设计好。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-4-25 17:11

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表