Fortran Coder

查看: 9292|回复: 8
打印 上一主题 下一主题

[讨论] 两种构造方法的区别

[复制链接]

146

帖子

42

主题

1

精华

宗师

F 币
1273 元
贡献
629 点
跳转到指定楼层
楼主
发表于 2019-6-8 17:55:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 weixing1531 于 2019-6-27 20:24 编辑

方法1:传统方法
模块中
[Fortran] 纯文本查看 复制代码
type,public :: rational !分数类
    private
    integer :: num    ! 分子
    integer :: denom  ! 分母
contains
    private
    procedure,pass(this),public :: rational=>new
end type rational
...
subroutine new(this,nn,dd) !构造函数
    class(rational), intent(out) :: this
    integer, intent(in) :: nn,dd
    ...
end subroutine new

主程序中
[Fortran] 纯文本查看 复制代码
type(rational)::a
call a%rational(1,2)

方法2:GitHub上大牛们喜欢用
模块中
[Fortran] 纯文本查看 复制代码
type,public :: rational !分数类
    private
    integer :: num    ! 分子
    integer :: denom  ! 分母
contains
    private
    ...
end type rational

interface rational
    procedure :: new
end interface
...
function new(nn,dd) result(rs)
    integer, intent(in) :: nn,dd
    type(rational)::rs
    ...
end function new

主程序中
[Fortran] 纯文本查看 复制代码
type(rational)::a
a=rational(1,2)

两种构造方法有什么区别呢?
个人理解
方法1:构造方法是子例程,属于实例方法,子类可以继承或重写父类的构造方法,子类重写构造方法时可用call this%父类名%构造方法名()来节省对象初始化的代码量
方法2:构造方法是函数,属于模块方法(实用方法),采用接口名与类名重名的方式,在属性私有前提下实现了结构构造器,子类不可以继承父类的构造函数,需要在子类所在模块中手动写构造函数(不能与父类构造函数重名)




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

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
沙发
发表于 2019-6-8 21:41:20 | 只看该作者
这个东西,我感觉只是偏好问题
大牛们的那种写法,纯粹只是写C语言或者python之类的类构造函数写习惯了
想保持风格一致避免犯错而已……

另外,我觉得你认为构造函数需要继承,这似乎不应该是个很安全的想法……
虽然似乎python里边是可以这么继承的
但是我觉得对每个类单独设置一个构造函数名可能会更安全一点
就是会增加一些工作量,也可能会带来一些疏忽……

835

帖子

2

主题

0

精华

大宗师

F 币
3926 元
贡献
2334 点
板凳
发表于 2019-6-13 09:53:33 | 只看该作者
我倾向于用第一种,rational是成员函数,结构更加紧密。

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
地板
发表于 2019-6-13 11:31:27 | 只看该作者
li913 发表于 2019-6-13 09:53
我倾向于用第一种,rational是成员函数,结构更加紧密。

这都是fortran没有真正的构造函数带来的问题啊
fortran向oop的转化太不彻底了

146

帖子

42

主题

1

精华

宗师

F 币
1273 元
贡献
629 点
5#
 楼主| 发表于 2019-6-13 20:09:53 | 只看该作者
本帖最后由 weixing1531 于 2019-6-15 15:37 编辑

方法3
模块中
[Fortran] 纯文本查看 复制代码
type,public :: rational !分数类
    private
    integer :: num    ! 分子
    integer :: denom  ! 分母
contains
    private
    procedure,nopass,public :: rational=>new
end type rational
...
function new(nn,dd) result(rs)
    integer, intent(in) :: nn,dd
    type(rational)::rs

    rs%num = nn
    rs%denom = dd
end function new

主程序中
[Fortran] 纯文本查看 复制代码
type(rational)::a
a=a%rational(1,2)


当然这种构造方法看起来有点丑陋

总结:
方法1  构造方法是成员过程,但是子例程,与其他语言构造方法差异较大
方法2  构造方法不是成员过程,但是函数,用起来方便
方法3  构造方法是成员过程,也是函数,有点丑陋




146

帖子

42

主题

1

精华

宗师

F 币
1273 元
贡献
629 点
6#
 楼主| 发表于 2019-6-19 20:33:55 | 只看该作者
liudy02 发表于 2019-6-8 21:41
这个东西,我感觉只是偏好问题
大牛们的那种写法,纯粹只是写C语言或者python之类的类构造函数写习惯了
想 ...

当然是能偷懒则偷咯
call this%父类名%父类构造方法

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
7#
发表于 2019-6-26 22:48:56 | 只看该作者
666
一个有意思的话题
如果存在多种够造函数,确实方法2更好
但如果只有一种,那1更好

个人愚见

146

帖子

42

主题

1

精华

宗师

F 币
1273 元
贡献
629 点
8#
 楼主| 发表于 2019-6-27 20:08:39 | 只看该作者
本帖最后由 weixing1531 于 2019-6-27 20:11 编辑
lookbook 发表于 2019-6-26 22:48
666
一个有意思的话题
如果存在多种够造函数,确实方法2更好

方法1也可以通过generic设置多种构造方法的通用名称

79

帖子

17

主题

0

精华

专家

齊天大聖

F 币
433 元
贡献
266 点
9#
发表于 2019-6-27 22:50:24 | 只看该作者
weixing1531 发表于 2019-6-27 20:08
方法1也可以通过generic设置多种构造方法的通用名称

那不是很累,也许子类就用不到那么多够造办法,还要一个一个去给它“注销”掉。但第二种办法相对安全点,新的类,无论有没有继承关系,新的够造办法,不存在多出来的情况。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

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

GMT+8, 2024-11-23 23:03

Powered by Tencent X3.4

© 2013-2024 Tencent

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