对于Fortran中的扩展类型,应该通过对不同模块中的类型扩展可见私有组件。
使用gcc4.7和ifort时,以下代码会导致错误,因为bName同时包含初始类型和扩展名。但由于它是私有的,因此在不同模块的扩展中是不可访问的,即,如果你在bar_type中注释掉bName,你将收到一个私有的错误。
module foo
type :: foo_type
character(256),private :: bName = "foo"
contains
procedure :: pName => pName
end type
contains
subroutine pName(this)
class(foo_type), intent(in) :: this
print*,trim(this%bName)
end subroutine
end module
module bar
use foo, only : foo_type
type,extends(foo_type) :: bar_type
character(256),private :: bName = "bar"
contains
procedure :: pName => pName
end type
contains
subroutine pName(this)
class(bar_type), intent(in) :: this
print*,this%bName
end subroutine
end module
program test
use foo, only : foo_type
use bar, only : bar_type
type(foo_type) :: foo_inst
type(bar_type) :: bar_inst
call foo_inst%pName()
call bar_inst%pName()
end program
如果bar_type包含在与foo_type相同的模块中,则可以从bar_type访问bName,即,以下代码将被编译
module foo
type :: foo_type
character(256),private :: bName = "foo"
contains
procedure :: pName => pName
end type
type, extends(foo_type) :: baz_type
contains
procedure :: pName => pName_baz
end type
contains
subroutine pName_baz(this)
class(baz_type), intent(in) :: this
print*,trim(this%bName)
end subroutine
subroutine pName(this)
class(foo_type), intent(in) :: this
print*,trim(this%bName)
end subroutine
end module
program test
use foo, only : foo_type,baz_type
type(foo_type) :: foo_inst
type(baz_type) :: baz_inst
call foo_inst%pName()
call baz_inst%pName()
end program
很难解析标准以了解第一个例子中应该发生的事情。
答案 0 :(得分:2)
我认为第一个例子不符合标准。
即使私有属性使组件bName
在模块foo
外部不可访问,它仍然由bar_type
继承(可能相当无意义,因为没有任何东西可以用它完成,但那是不是问题) - 参见f2003中的注释4.51:
父类型的无法访问的组件和绑定也是继承的,但它们仍然无法访问 在扩展类型中。如果通过访问扩展类型,则会出现无法访问的实体 使用关联并拥有私人实体。
所以bar_type
有一个名为bName
的继承组件,这使得用该名称添加另一个组件是错误的(参见第16.2节的范围和名称规则)。