Fortran Coder

查看: 19591|回复: 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内使用。

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


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

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
19#
 楼主| 发表于 2019-7-7 15:01:55 | 只看该作者
weixing1531 发表于 2019-7-6 21:41
楼主的设想还是可以实现的
只是class(*)多态指针p的断开引用必须在select type内部才行     
  但Fortran20 ...

我没明白你的意思,看了下代码,这还是要在select type里才能进行操作(包括绑定的过程的调用)啊。

146

帖子

42

主题

1

精华

宗师

F 币
1273 元
贡献
629 点
18#
发表于 2019-7-6 21:41:19 | 只看该作者
本帖最后由 weixing1531 于 2019-7-6 22:08 编辑

楼主的设想还是可以实现的
只是class(*)多态指针p的断开引用必须在select type内部才行     
  但Fortran2018标准已经放松该限制  
  摘自电子书《Modern Fortran Explained  Incorporating Fortran 2018
  下载网址:http://www.doc88.com/p-0601727992809.html

[Fortran] 纯文本查看 复制代码
program main
    implicit none
    integer,target::a=3
    real,target::b=8.15
    class(*),pointer::p
    
    ALLOCATE(p,source=a) !f2018标准支持 p=a
    call write_p(p)
    p=>b
    call write_p(p)
    ALLOCATE(p,source=b) !f2018标准支持 p=b
    call write_p(p)
    p=>a
    call write_p(p)
contains
    subroutine write_p(p)
        class(*),pointer,intent(in)::p

        select type(p)
        type is(integer)
            write(*,"(I3)")p
        type is(real)
            write(*,"(F8.2)")p
        end select
    end subroutine write_p
end program






2022

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1598 元
贡献
689 点

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

17#
发表于 2019-7-4 17:39:54 | 只看该作者
差不多是这样。fortran语法太严苛,保证安全的同时,也有失灵活。
大多数时候,没必要这么做。
一部分过程,如果传入类型不重要,只是单纯的做别的事情,把传入参数直接传走,可以考虑用class(*)

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
16#
发表于 2019-7-4 13:34:24 | 只看该作者
lookbook 发表于 2019-7-4 11:05
我的本意是为什么要用c_f_pointer这个函数

我没用过c和 fortran的交互
印象中,似乎fortran 的位操作都是假操作,还限定整数类型
所以我虽然没看懂版主是怎么做的,但是应该是把fortran的指针和c的指针相互转换
然后利用c来不分类型地对位进行倒置

2022

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1598 元
贡献
689 点

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

15#
发表于 2019-7-4 11:21:48 | 只看该作者
gfortran的 c_loc 不支持多态的话,可能就麻烦点,得用不规范的 loc

  Subroutine CnvrtEndian( byteIn , nByte )
    use , intrinsic :: ISO_C_Binding
    class(*) , target , Intent(INOUT) :: byteIn
    integer  , Intent(IN)             :: nByte
    character , pointer :: p(:)
    type(c_ptr) :: cp
    cp = transfer( loc(byteIn) , cp )
    call c_f_pointer( cp , p , [nByte] )
    p = p(nByte:1:-1)
  End Subroutine CnvrtEndian

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
14#
 楼主| 发表于 2019-7-4 11:05:45 | 只看该作者
liudy02 发表于 2019-7-3 22:53
难道不是c_f_pointer这个子进程属于iso_c_binding这个内部模块?

用父类确实可以实现一定程度的多态,但 ...

我的本意是为什么要用c_f_pointer这个函数

2022

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1598 元
贡献
689 点

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

13#
发表于 2019-7-4 08:46:11 | 只看该作者
fortran语法设计得比较严谨,不确切的、可能因疏忽导致莫名其妙错误的,都被严格禁止了。

8

帖子

2

主题

0

精华

入门

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

其他语言,你会不知道怎么死的,特别是业务逻辑多的。
fortran的优点就是太傻了,不按照他的语法就是不过。

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
11#
发表于 2019-7-3 22:53:12 | 只看该作者
本帖最后由 liudy02 于 2019-7-3 22:54 编辑
lookbook 发表于 2019-7-3 22:39
谢谢绝地,
但这个代码在gfortran下测试并不成功,c_f_pointer不接受多态的指针,pgi是可以的,我猜ivf也 ...

难道不是c_f_pointer这个子进程属于iso_c_binding这个内部模块?

用父类确实可以实现一定程度的多态,但我认为还是很不理想的
多态进程中涉及到的成员变量在某个子类里有变化可能就会要重载一堆方法
而且多数时候事情没那么复杂,可能就是想省码点包含基本运算的代码
结果却要层层设置类树,设置一堆运算符之类的,麻烦要死
所以我很欣赏有位大佬在这里推荐的在fortran里写模块的办法
只是那个办法也是建立在C预处理的基础上的
如果不是和C编译器继承在一起的fortran编译器,事情就麻烦的多了……
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

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

GMT+8, 2024-11-23 22:14

Powered by Tencent X3.4

© 2013-2024 Tencent

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