Fortran Coder

标题: 两种构造方法的区别 [打印本页]

作者: weixing1531    时间: 2019-6-8 17:55
标题: 两种构造方法的区别
本帖最后由 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:构造方法是函数,属于模块方法(实用方法),采用接口名与类名重名的方式,在属性私有前提下实现了结构构造器,子类不可以继承父类的构造函数,需要在子类所在模块中手动写构造函数(不能与父类构造函数重名)





作者: liudy02    时间: 2019-6-8 21:41
这个东西,我感觉只是偏好问题
大牛们的那种写法,纯粹只是写C语言或者python之类的类构造函数写习惯了
想保持风格一致避免犯错而已……

另外,我觉得你认为构造函数需要继承,这似乎不应该是个很安全的想法……
虽然似乎python里边是可以这么继承的
但是我觉得对每个类单独设置一个构造函数名可能会更安全一点
就是会增加一些工作量,也可能会带来一些疏忽……
作者: li913    时间: 2019-6-13 09:53
我倾向于用第一种,rational是成员函数,结构更加紧密。
作者: liudy02    时间: 2019-6-13 11:31
li913 发表于 2019-6-13 09:53
我倾向于用第一种,rational是成员函数,结构更加紧密。

这都是fortran没有真正的构造函数带来的问题啊
fortran向oop的转化太不彻底了
作者: weixing1531    时间: 2019-6-13 20:09
本帖最后由 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  构造方法是成员过程,也是函数,有点丑陋





作者: weixing1531    时间: 2019-6-19 20:33
liudy02 发表于 2019-6-8 21:41
这个东西,我感觉只是偏好问题
大牛们的那种写法,纯粹只是写C语言或者python之类的类构造函数写习惯了
想 ...

当然是能偷懒则偷咯
call this%父类名%父类构造方法
作者: lookbook    时间: 2019-6-26 22:48
666
一个有意思的话题
如果存在多种够造函数,确实方法2更好
但如果只有一种,那1更好

个人愚见
作者: weixing1531    时间: 2019-6-27 20:08
本帖最后由 weixing1531 于 2019-6-27 20:11 编辑
lookbook 发表于 2019-6-26 22:48
666
一个有意思的话题
如果存在多种够造函数,确实方法2更好

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

作者: lookbook    时间: 2019-6-27 22:50
weixing1531 发表于 2019-6-27 20:08
方法1也可以通过generic设置多种构造方法的通用名称

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




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2