指向父 class 的多态指针不起作用
Polymorphic pointer to parent class not working
考虑以下 class 结构,它涉及三个独立的模块:
!-------------------- 在文件 a.f
module parent_body_mod
type :: face
class(parent_body), pointer :: bPtr
end type
type, abstract :: parent_body
integer i
type(face) :: f
end type
end module parent_body_mod
!------------------------ 在文件 b.f
module body_mod
use parent_body_mod
type, extends(parent_body) :: body
end type
interface body
procedure :: new_body
end interface
contains
function new_body() result(b)
type(body), target :: b
b%i = 123
b%f%bPtr => b
end function
end module body_mod
!------------------------ 在文件 c.f
module body_group_mod
use body_mod
type :: body_group
type(body), allocatable :: b
end type
interface body_group
procedure :: new_body_group
end interface
contains
function new_body_group() result(bg)
type(body_group) :: bg
allocate(bg%b)
bg%b = body()
end function
end module body_group_mod
!-------------------- 主程序
use body_group_mod
type(body_group) :: my_bg
my_bg = body_group()
print *, my_bg%b%f%bPtr%i
end
!-------------------------------------
预期输出是 123,而 实际输出是随机的。代码是使用 ifort 版本 18.0.1 编译的。请注意,使用 "body" class 本身时不会发生同样的问题,即以下工作正常:
type(body), allocatable :: my_b
allocate(my_b)
my_b = body()
print *, my_b%f%bPtr%i ! This produces 123 as expected.
感谢任何帮助。
代码不符合规范。
当过程执行完成时,与过程的未保存局部变量关联的指针变为未定义 (F2008 16.5.2.5 (5))。函数new_body
中的函数结果b
被认为是这样的局部变量(F2008 1.3.154.1),因此指针组件b%f%bPtr
在函数调用后变为未定义。
与其他未保存的本地变量相比,函数结果有点特殊,因为它们的值可用的时间长于变量存在的时间 - 有关讨论,请参阅 F2008 注释 12.41。
另一种思考问题的方式是,对于语句 bg%b = body()
,左侧的 body 与左侧的 body 不同 object右手边。该赋值只是复制右侧 object 的值 - 一旦该赋值完成,右侧 object 将不复存在。没有任何代码可以说明当 body object 的值被传输时 - 指针组件需要更新以引用分配给的左侧变量。另请注意,左侧 bg%b
没有 TARGET 属性 - 因此无论如何都无法将指针与其有效关联。
考虑以下 class 结构,它涉及三个独立的模块:
!-------------------- 在文件 a.f
module parent_body_mod
type :: face
class(parent_body), pointer :: bPtr
end type
type, abstract :: parent_body
integer i
type(face) :: f
end type
end module parent_body_mod
!------------------------ 在文件 b.f
module body_mod
use parent_body_mod
type, extends(parent_body) :: body
end type
interface body
procedure :: new_body
end interface
contains
function new_body() result(b)
type(body), target :: b
b%i = 123
b%f%bPtr => b
end function
end module body_mod
!------------------------ 在文件 c.f
module body_group_mod
use body_mod
type :: body_group
type(body), allocatable :: b
end type
interface body_group
procedure :: new_body_group
end interface
contains
function new_body_group() result(bg)
type(body_group) :: bg
allocate(bg%b)
bg%b = body()
end function
end module body_group_mod
!-------------------- 主程序
use body_group_mod
type(body_group) :: my_bg
my_bg = body_group()
print *, my_bg%b%f%bPtr%i
end
!-------------------------------------
预期输出是 123,而 实际输出是随机的。代码是使用 ifort 版本 18.0.1 编译的。请注意,使用 "body" class 本身时不会发生同样的问题,即以下工作正常:
type(body), allocatable :: my_b
allocate(my_b)
my_b = body()
print *, my_b%f%bPtr%i ! This produces 123 as expected.
感谢任何帮助。
代码不符合规范。
当过程执行完成时,与过程的未保存局部变量关联的指针变为未定义 (F2008 16.5.2.5 (5))。函数new_body
中的函数结果b
被认为是这样的局部变量(F2008 1.3.154.1),因此指针组件b%f%bPtr
在函数调用后变为未定义。
与其他未保存的本地变量相比,函数结果有点特殊,因为它们的值可用的时间长于变量存在的时间 - 有关讨论,请参阅 F2008 注释 12.41。
另一种思考问题的方式是,对于语句 bg%b = body()
,左侧的 body 与左侧的 body 不同 object右手边。该赋值只是复制右侧 object 的值 - 一旦该赋值完成,右侧 object 将不复存在。没有任何代码可以说明当 body object 的值被传输时 - 指针组件需要更新以引用分配给的左侧变量。另请注意,左侧 bg%b
没有 TARGET 属性 - 因此无论如何都无法将指针与其有效关联。