Pap*_*Pap 10 inheritance fortran private parent-child
我正在寻找一种方法来从后代类访问Fortran类的私有组件(Fortran术语中的派生类型).例如,假设类A具有组件x,它被声明为私有.现在考虑继承自基类A的第二个类B.在这种情况下,类B没有对x的直接访问,因此不允许任何尝试访问B%x.我能想到的两个解决方案是:
(1)声明x为公共.但是,这将使x全局可访问,这会滥用数据隐藏,因此作为问题的可接受解决方案被拒绝.
(2)实现获取/设置A%x的过程,例如A%getX()和A%setX().这不仅麻烦,而且还允许(间接)访问程序中的A%x - 不仅仅是在子类中.
我想要的是一种从A的子类访问A%x的方法,但是否则x应该在其他地方不可访问.C++具有"受保护"属性用于此目的,但据我所知,Fortran 2003中的"protected"属性具有不同的含义(它使得A%x在任何地方都可访问并且仅保护其值,这在课堂外不能更改).
语言在一般意义上没有这种能力(除了高性能标记建议的一个模块方法中的所有内容之外),并且您并不是唯一想要这样做的人.
正如您在Mark的回答中所述,可访问性基于模块,而不是类型.
但请注意,使用子模块可能会部分解决您的问题.您使用HIgh Performance Mark建议的一个大模块方法,但该模块可以在多个程序单元之间拆分.实现类型绑定的过程可以作为单独的模块过程一起提供在子模块中,然后模块本身只保存类型定义和单独的接口主体.由于子模块在概念上是其祖先模块的一部分,因此仍可访问模块中私有的模块中的任何组件和类型.
Fortran和其他语言(例如C++)之间的一个概念差异在于,实际执行操作的过程不是类型的"部分" - 而是类型具有引用过程的绑定.来自多种类型的绑定可以参考一个过程.因此,在类型定义中,很清楚您是否在作为父类型的扩展的作用域中工作,在类型定义之外它不太清楚.实现此功能的语言工具需要以某种方式适应这种差异.
这可能是一个扩展评论而不是一个答案......
我不太明白你的问题,或者我不明白你想要做什么。我同意你的选择 (1) 没有吸引力,我们希望private组件是私有的。
但是当我谈到你的观点(2)时,我可以写一个这样的模块:
module types
type :: supertype
integer, private :: c1 = 1
end type supertype
type, extends(supertype) :: subtype
integer :: c2
contains
procedure, pass :: getc1
end type subtype
contains
integer function getc1(this)
class(subtype), intent(inout) :: this
this%c1 = 12 ! Just to show that the sub-type can set super-type components
getc1 = this%c1 ! Return the latest value of c1
end function getc1
end module types
Run Code Online (Sandbox Code Playgroud)
这编译没有错误(Intel Fortran 13.something)。这确实使getc1模块的所有用户都可以使用类型绑定过程。但是,如果我将过程声明从
procedure, pass :: getc1
Run Code Online (Sandbox Code Playgroud)
到
procedure, pass, private :: getc1
Run Code Online (Sandbox Code Playgroud)
该过程在模块外不再可用。在我看来,这就像一个子类型可以访问超类型的私有组件,而该访问权限不会泄漏到外部世界。
这段代码符合标准,因为我和我的编译器都理解标准。