【发布时间】:2014-10-14 03:37:15
【问题描述】:
我正在尝试理解 Fortran 2003 标准(或更高版本)中的面向对象概念。我对 C++ 有一些了解,所以我认为这两种语言之间有一些共同的想法可以帮助我更好地理解它们。
在 C++ 中,多态性是通过类派生和成员函数覆盖来完成的。一个定义了一个“抽象”基类,其中几乎所有的虚函数都被定义了。不同的派生类包含它们的实际实现。所以其他功能只需要基于“抽象”类进行编程即可。然后它们适用于所有派生类。
我认为在 Fortran 中,OOP 以类似的方式完成,但存在一些差异。在我看来,需要像 C++ 一样定义一个带有一些虚函数的基类型。其他函数/子例程应遵循基类型中的成员函数定义。这就是解决所有扩展类型的函数/子例程重用的方法。
我对如何编程这个想法没有更好的想法。这是我的第一次尝试:
type Basis
integer :: NBasis
contains
private
procedure :: DoNothing
generic, public :: Constructor => DoNothing
generic, public :: AllocateBasis => DoNothing
endtype Basis
type, extends(Basis) :: GridBasis
private
integer :: NGrid
contains
private
procedure :: ConstructorGrid1
procedure :: ConstructorGrid2
generic, public :: Constructor => ConstructorGrid1, ConstructorGrid2, ConstructorGrid3
procedure :: AllocateGridReal
procedure :: AllocateGridCplx
generic, public :: AllocateBasis => AllocateGridReal, AllocateGridCplx
endtype GridBasis
首先,如何在类型 Basis 中定义“AllocateBasis”,使其像“虚拟函数”一样工作,并且所有扩展类型都必须定义自己的“AllocateBasis”版本?
其次,如何在GridBasis类型中定义“AllocateBasis”?这里的定义包含了它的真正实现。
第三,如何让GridBasis类型的“AllocateBasis”成为重载函数?即有真实版本和复杂版本,它们都被命名为“AllocateBasis”,带有真实或复杂的输入可分配数组。
第四,NOPASS 与 PASS。据我了解,如果设置了 PASS,则有一个指向该对象的显式指针。但是当设置了 NOPASS 时,就没有这样的事情了。所以PASS是为了澄清而简化?
【问题讨论】:
-
我的目标是将 Solver 例程和基础类型分开。你说的对。我会立即在我的帖子中添加一个示例。感谢您的回复:)
-
您现在有了一个合理的通用答案,可以轻松适应您的具体情况。而且您的编辑澄清了您知道您不需要在任何地方都做基本的事情(但在这里很有用)。
标签: inheritance polymorphism fortran overriding