考虑以下代码
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
。任何人都可以帮助
答案 0 :(得分:2)
至于“为什么我们不能访问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
如果Line1取消注释,则会出现错误(使用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'?
我猜情况与其他(静态类型的)语言相似。例如,当我们访问ptr->b
时,以下C ++代码给出了错误。
#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;
}
答案 1 :(得分:0)
为了访问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