Создание объектов на лету и доступ через родительский класс - PullRequest
0 голосов
/ 23 января 2020

В настоящее время у меня есть структура класса, которая выглядит следующим образом:

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

Итак, если я создаю ObjectA где-то еще, я также создаю ObjectB и Object C. Но я бы предпочел иметь что-то вроде

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 и Object C определены правильно (существует переменная "initialized"). В настоящее время я получаю сообщение об ошибке «Это не имя поля, которое определено в охватывающей структуре». из команды печати. ​​

Я чувствую, что я близко, но я не могу заставить его работать. Как мне это сделать?

1 Ответ

1 голос
/ 23 января 2020

Этого можно добиться, сделав объекты типа 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 везде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...