【问题标题】:Create objects on the fly and access via parent class动态创建对象并通过父类访问
【发布时间】:2020-05-09 20:42:57
【问题描述】:

目前我的类结构如下:

 type, public :: ClassA      
    type(ClassB), public :: ObjectB
    type(ClassC), public :: ObjectC
 end type ClassA

也就是说,如果我在其他地方创建 ObjectA,我也会创建 ObjectB 和 ObjectC。但我宁愿有类似的东西

type, public :: ClassA  
    contains
        procedure, public :: CreateObjectB
        procedure, public :: CreateObjectC
end type 
contains
subroutine CreateObjectB(self)
    class(ClassA) :: self
    type(ClassB) :: ObjectB
    ObjectB%initialized = 1
end subroutine
subroutine CreateObjectC(self)
    class(ClassA) :: self
    type(ClassC) :: ObjectC
    ObjectC%initialized = 1
end subroutine

换句话说,就是有可能创建这些对象。 然后,从外部,我想动态创建对象:

type(ClassA) :: ObjectA
call ObjectA%CreateObjectB()
print*,ObjectA%ObjectB%intialized

假设 ObjectB 和 ObjectC 被正确定义(变量“initialized”存在)。 目前我收到错误“这不是在包含结构中定义的字段名称。”来自打印命令。

我觉得我很接近,但我无法让它工作。我该怎么做?

【问题讨论】:

  • 如果您为您提供完整的示例代码,并定义并初始化 ObjectB、ObjectC 等,一旦错误也可能存在,那就好多了
  • 另外请注意,通过在 CreateObjectB 中定义 ObjectB 的方式,ObjectB 将仅在 CreateObjectB 的特定运行期间可用。如果您希望它在子例程执行后可用,以便您可以调用print*,ObjectA%ObjectB%intialized,您必须将其保存为 ClassA 的属性,就像您在开始时所做的那样。另一种选择是将 CreateObjectB 设置为函数并将其返回给分配函数的变量。
  • 你想在另一个对象的实例中拥有不确定数量的实例和对象吗?
  • 我不确定我是否完全遵循,所以这可能偏离目标:如果您希望能够创建 A 而无需同时创建 BC同时,您可以将它们都设为allocatabletype A 的成员,然后在需要时分配它们。或者您是否希望能够创建 B 并稍后将其与 A 关联?

标签: oop fortran


【解决方案1】:

您可以通过使classA 中的对象类型为allocatable 来实现这一点,如下所示:

module classA_module
        use classB_module
        use classC_module
implicit none
type :: classA
      type(classB), allocatable :: objectB
      type(classC), allocatable :: objectC
    contains
        procedure  :: init          => init_classA
        procedure  :: check_isInit  => check_isInit_classA
end type classA
        contains
                subroutine init_classA(this)
                        class(classA) :: this
                        allocate ( classB :: this%objectB )
                        allocate ( classC :: this%objectC )
                        ! initialize objectB (sets objectB%initialized = .true. internally)
                        call this%objectB%init()
                        call this%objectC%init()
                end subroutine init_classA
                subroutine check_isInit_classA(this)
                        class(classA) :: this
                        if ( this%objectB%isinitialized ) then
                                print*,'Initialization was successful'
                        else
                                print*,'Initialization failed'
                        endif
                        print*,'this%objectB%isinitialized: ',this%objectB%isinitialized
                        print*,'this%objectC%isinitialized: ',this%objectC%isinitialized
                end subroutine check_isInit_classA
end module classA_module

module classB_module
implicit none
type :: classB
        logical :: isInitialized = .false.
    contains
        procedure  :: init  => init_classB
end type classB
        contains
                subroutine init_classB(this)
                        class(classB) :: this
                        this%isInitialized = .true.
                end subroutine init_classB
end module classB_module

PROGRAM Main
      use classA_module
      implicit none
      type(classA) :: objectA
      call objectA%init()
      call objectA%check_isInit()
end program Main

我省略了classC_module 以节省空间。它是classB_module 的复制/粘贴,只需在各处将 B 替换为 C。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多