Проблема с доступом к дочернему объявленному типу в Фортране - PullRequest
0 голосов
/ 16 января 2019

Рассмотрим следующий код

  module class_type

  implicit none
  class(*), pointer :: fnzo => null()


  type, abstract :: gen

     real :: ss
     integer :: sdsd
     class(gen), pointer    :: next =>null()
  end type

  type, extends(gen) :: final1

     real :: ss1

  end type final1

  type, extends(gen) :: final2

  real :: x1(10)

  end type


  end module class_type



  program test_class

  use class_type

  implicit none

  class(gen), pointer :: test
  type(final1) :: test1
  allocate(test, source = test1)

  print*, test% ss1




  end program

Я пытаюсь составить связанный список, в котором каждый следующий элемент наследует final1 или final2. В настоящее время просто тестирую простые случаи, и я не понимаю, почему я не могу получить доступ к test%ss1. Любой, кто поможет

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Что касается «почему мы не можем получить доступ к test% ss1», следующий код может быть полезен для рассмотрения причины. В этом коде я получаю пользовательский ввод (inp) и определяю, указывает ли ptr на переменные типа test1 или test2. Если ptr указывает на переменную test2, доступ к ptr% ss1 явно не имеет смысла, поэтому компилятору необходимо защититься от такого неправильного доступа. Я думаю, именно поэтому компилятор разрешает доступ только к компонентам gen (= объявленный тип), если не указано select type (для реальных данных в памяти).

program test_class
  use class_type
  implicit none
  class(gen), pointer  :: ptr    !! parent type
  type(final1), target :: test1  !! child type
  type(final2), target :: test2  !! child type
  integer :: inp

  print *, "input some integer"
  read *, inp

  if ( inp == 1 ) ptr => test1
  if ( inp == 2 ) ptr => test2

  print*, "ptr% ss = ", ptr% ss   !! OK

  ! print*, "ptr% ss1 = ", ptr% ss1  !! error (Line1)

  select type ( ptr )
    type is ( final1 ); print*, "ss1 = ", ptr% ss1  !! OK
    type is ( final2 ); print*, "x1  = ", ptr% x1   !! OK
  endselect

end program

Если строка 1 не закомментирована, выдает ошибку (с gfortran-8)

   print*, "ptr% ss1 = ", ptr% ss1  !! error
                             1
Error: 'ss1' at (1) is not a member of the 'gen' structure; did you mean 'ss'?

Я полагаю, что ситуация похожа на другие (статически типизированные) языки. Например, следующий код на C ++ выдает ошибку при доступе к ptr->b.

#include <iostream>
using namespace std;

struct A {
    int a = 1;
};
struct B : A {
    int b = 100;
};

int main() {
    A *ptr;
    ptr = new B;
    cout << ptr->a << endl;     // 1
    // cout << ptr->b << endl;  // error: 'struct A' has no member named 'b'
    delete ptr;
}
0 голосов
/ 16 января 2019

Чтобы получить доступ к ss1, вам нужен указатель в вашем абстрактном классе на дочерний объект. Указатель может иметь любое расширение типа, которое вы хотите определить. Поскольку в вашем связанном списке есть два разных расширения типа, вам необходимо объявить два дочерних указателя в вашем абстрактном классе.

module class_type

  implicit none
  class(*), pointer :: fnzo => null()


  type, abstract :: gen

     real :: ss
     integer :: sdsd
     class(gen), pointer    :: next =>null()
     type(final1), pointer  :: child
  end type

  type, extends(gen) :: final1

     real :: ss1

  end type final1

  type, extends(gen) :: final2

     real :: x1(10)

  end type final2


end module class_type



program test_class

  use class_type

  implicit none

  class(gen), pointer  :: test
  type(final1), target    :: test1

  allocate(test, source=test1)

  test1% ss1 = 20.0
  test% child => test1

  write(*,*) test1% ss1

  write(*,*) test% child% ss1

end program test_class

Когда вы скомпилируете и выполните, вы увидите:

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