Is it currently possible to override the structure constructor in Fortran?
号不管怎么说即使使用你的方法也完全不是构造器重写。主要原因是结构构造器#OOP构造函数。有一些相似之处,但这只是另一个想法。
您不能在初始化表达式中使用您的非内在函数。您只能使用常量,数组或结构构造函数,内部函数...有关更多信息,请参阅Fortran 2003草稿中的7.1.7初始化表达式。
考虑这一事实考虑我完全不明白是什么
type(mytype) :: x
x = mytype(0)
和
type(mytype) :: x
x = init_mytype(0)
,什么是使用mymod模块内部接口块的整点之间的真正区别。
那么,说实话,这是一个巨大的 - 第一种方式是误导。这个函数不是构造函数(因为在Fortran中根本没有OOP构造函数),它是一个初始化器。
在主流的面向对象的构造函数负责顺序做两件事情:
- 内存分配。
- 成员初始化。
让我们来看看实例化不同语言类的一些例子。
在的Java:
MyType mt = new MyType(1);
一个非常重要的事实是隐藏的 - 事实的对象实际上是一个指向类类型的varibale。在C++相当于将是堆分配使用:
MyType* mt = new MyType(1);
但在两种语言中可以看出,两个构造职责,即使在语法层面的体现。它由两部分组成:关键字new(分配)和构造函数名称(初始化)。在Objective-C的语法这个事实更是强调:
MyType* mt = [[MyType alloc] init:1];
但很多时候,你可以看到构造函数调用的一些其他形式。在堆栈ç分配的情况下++使用特殊(很差)语法结构
MyType mt(1);
这实际上是重大的误导性,我们可以直接不考虑它。
在的Python
mt = MyType(1)
两个事实对象实际上是一个指针和一个事实,即分配首先发生被隐藏(在语法级别)。而这种方法被称为... __init__
! O_O如此误导。 С++堆栈分配与那个相比褪色。 =)
反正有构造的语言的想法意味着做在一个声明中分配初始化的能力,使用一些特殊的方法。如果你认为这是“真正的面向对象”方式,我对你有坏消息。即使Smalltalkdoesn't have constructors。它只是一个约定,对类本身有一个new
方法(它们是元类的单例对象)。 Factory Design Pattern在许多其他语言中用于实现相同的目标。
我在某处读到Fortran模块的概念是受Modula-2启发的。在我看来,OOP功能受到Oberon-2的启发。 Oberon-2中也没有施工人员。但是,当然有纯粹的预先分配的程序NEW(比如Fortran中的ALLOCATE,但ALLOCATE是语句)。分配后,你可以(应该在实践中)调用一些初始化程序,这只是一个普通的方法。没有什么特别的。
所以你可以使用某种工厂来初始化对象。这就是你实际使用模块而不是单身对象所做的事情。或者说他们(Java/C#/ ...程序员)使用单例对象方法而不是普通函数会更好,因为缺少后者(没有模块 - 没有办法只有普通函数,只有方法)。
您也可以使用type-bound SUBROUTINE。
MODULE mymod
TYPE mytype
PRIVATE
INTEGER :: x
CONTAINS
PROCEDURE, PASS :: init
END TYPE
CONTAINS
SUBROUTINE init(this, i)
CLASS(mytype), INTENT(OUT) :: this
INTEGER, INTENT(IN) :: i
IF(i > 0) THEN
this%x = 1
ELSE
this%x = 2
END IF
END SUBROUTINE init
END
PROGRAM test
USE mymod
TYPE(mytype) :: x
CALL x%init(1)
END PROGRAM
INTENT(OUT)
为this
ARG init
子程序似乎是罚款。因为我们希望这种方法在分配后只调用一次。可能是一个好主意来控制这个假设不会错。要添加一些布尔标志LOGICAL :: inited
到mytype
,检查它是否为.false.
,并在第一次初始化时将其设置为.true.
,并在尝试重新初始化时执行其他操作。我绝对记得有关Google Groups的一些主题......我无法找到它。
谢谢,修复。为分心的错误道歉,这是一个匆忙的例子。 – 2010-11-24 10:36:18