4

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 相同的模块中,则 bName 可以从 bar_type 访问,即,以下代码将编译

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

很难解析标准以了解第一个示例中应该发生什么。

4

1 回答 1

2

我相信第一个例子不符合标准。

即使 private 属性使组件bName在 module 外部不可访问foo,它仍然被继承bar_type(也许相当没有意义,因为它不能做任何事情,但这不是问题)——参见 f2003 中的注释 4.51:

父类型的不可访问组件和绑定也被继承,但它们在扩展类型中仍然不可访问。如果通过使用关联访问被扩展的类型并且具有私有实体,则会出现不可访问的实体。

所以bar_type有一个名为 的继承组件bName,这使得以该名称添加另一个组件是错误的(有关范围和名称规则,请参见第 16.2 段)。

于 2012-07-03T00:54:06.233 回答