Что касается «почему мы не можем получить доступ к 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;
}