oop - 如何在 Fortran 中使用多态数据类型作为另一种数据类型的属性
问题描述
我创建了一个名为“元素”的类,它有几个属性和类型绑定的过程。其中一个属性是具有两个继承类型“kin1”和“kin2”的抽象类类型“kin”。我希望能够在运行时根据输入使用构造函数将“kin1”或“kin2”作为属性分配给对象“元素”。目标是有一个元素列表,每个元素的 element%kin 要么是“kin1”类型,要么是“kin2”类型。
模块元素
模块元素
使用亲属
implicit none
type,public :: element_type
class(kin_type),allocatable :: kin
contains
procedure,pass(this), private :: set_kin
procedure,pass(this), public :: get_kin
end type element_type
interface element_type
module procedure element_type_constructor
end interface element_type
包含
type (element_type) function element_type_constructor(kin)
implicit none
class(kin_type),allocatable, intent (in) :: kin
call element_type_constructor%set_kin(kin)
end function element_type_constructor
! my try of set_kin
subroutine set_kin(this,kin)
implicit none
class(element_type), intent(inout) :: this
class(kin_type),allocatable, intent(in) :: kin
this%kin = kin
end subroutine
端模块元件
模块亲属
模块 kin 隐式 无 私有
type,abstract :: kin_type
end type kin_type
type,public, extends(kin_type) :: kin1_type
private
integer :: data1
contains
procedure,pass(this),private :: set_data1
procedure,pass(this),public :: get_data1
procedure,pass(this),public :: print =>print_kin1
end type kin1_type
type,public, extends(kin1_type) :: kin2_type
private
real :: data2
contains
procedure,pass(this),private :: set_data2
procedure,pass(this),public :: get_data2
procedure,pass(this),public :: print =>print_kin2
end type kin2_type
! constructor interface kin1_type
interface kin1_type
module procedure kin1_type_constructor
end interface kin1_type
! constructor interface kin2_type
interface kin2_type
module procedure kin2_type_constructor
end interface kin2_type
包含
! constructor kin1_type
type (kin1_type) function kin1_type_constructor(data1)
implicit none
integer, intent (in) :: data1
class(kin1_type), intent (in) :: kin
call kin1_type_constructor%set_data1(data1)
end function kin1_type_constructor
! constructor kin2_type
type (kin2_type) function kin1_type_constructor(data1,data2)
implicit none
integer, intent (in) :: data1
real, intent (in) :: data2
class(kin2_type), intent (in) :: kin
call kin2_type_constructor%set_data1(data1)
call kin2_type_constructor%set_data2(data2)
end function kin2_type_constructor
! Example of set subroutine
subroutine set_data1(this,data1)
class(kin1_type),intent(inout) :: this
integer, intent(in) :: data1
this%data1 = data1
end subroutine set_data1
!其他手续...
端模块kin
程序
程序测试
use element
use kin
implicit none
type(element_type) :: thisElement
type(kin1_type) :: thisKin1
! constructor for thisKin1
thisKin1 = kin1_constructor(data1 = 1)
! constructor for thisElement
thisElement = element_type_constructor(kin = thisKin1)
! Check kin structure and values
call thisElement%kin%print
结束程序
错误
我在 element_type_constructor 子例程运行期间收到以下错误:程序收到信号 SIGSEGV:分段错误 - 内存引用无效。
解决方案
我还不能发表评论,所以这是第一个答案:不幸的是,提供的代码不完整。此外,缺少编译器的供应商和版本,这使得很难猜测实际问题是什么。
“修复”代码以获取以下示例表明它原则上是有效的:
kin.f90:
module kin
implicit none
private
type,abstract,public :: kin_type
contains
procedure(print_iface), deferred :: print
end type kin_type
type,public, extends(kin_type) :: kin1_type
private
integer :: data1
contains
procedure,pass(this),private :: set_data1
procedure,pass(this),public :: print => print_kin1
end type kin1_type
! constructor interface kin1_type
interface kin1_type
module procedure kin1_type_constructor
end interface kin1_type
abstract interface
subroutine print_iface(this)
import kin_type
class(kin_type), intent(in) :: this
end subroutine
end interface
contains
! constructor kin1_type
type (kin1_type) function kin1_type_constructor(data1)
implicit none
integer, intent (in) :: data1
call kin1_type_constructor%set_data1(data1)
end function kin1_type_constructor
! Example of set subroutine
subroutine set_data1(this,data1)
class(kin1_type),intent(inout) :: this
integer, intent(in) :: data1
this%data1 = data1
end subroutine set_data1
subroutine print_kin1(this)
class(kin1_type),intent(in) :: this
print *, this%data1
end subroutine print_kin1
end module kin
元素.f90:
module element
use kin, only: kin_type
implicit none
type,public :: element_type
class(kin_type), allocatable :: kin
contains
procedure,pass(this), private :: set_kin
end type element_type
interface element_type
module procedure element_type_constructor
end interface element_type
contains
type (element_type) function element_type_constructor(kin)
implicit none
class(kin_type), intent (in) :: kin
call element_type_constructor%set_kin(kin)
end function element_type_constructor
! my try of set_kin
subroutine set_kin(this,kin)
implicit none
class(element_type), intent(inout) :: this
class(kin_type), intent(in) :: kin
this%kin = kin
end subroutine
end module element
main.f90:
program test
use element
use kin
implicit none
type(element_type) :: thisElement
class(kin_type), allocatable :: thisKin1
! constructor for thisKin1
thisKin1 = kin1_type(data1 = 1)
! constructor for thisElement
thisElement = element_type(kin = thisKin1)
call thisElement%kin%print()
end program
使用 gfortran 7.4.0 构建它并运行它会产生:
$ gfortran -o prog kin.f90 element.f90 main.f90
$ ./prog
1
$
与所提供内容的一个显着区别是抽象类型上的延迟print
过程,因为它是通过定义为 a 的属性调用的class(kin_type)
。不幸的是,这并不能解释引用的错误。
推荐阅读
- python - 从请求处理程序将项目添加到异步队列
- python - 如何遍历文件夹中的文件并使用powershell在它们上运行特定的python代码?
- android - Gradle 无法解析本地 aar 依赖
- android - 如何在更新字段值时触发 Firestore 云功能?
- javascript - 函数中的 return (string.splice(" ").join"") 与 string.splice(" ").join("") 有何不同,然后返回字符串?
- c# - 如何在数据列表中提取版本名称?
- php - WordPress 如何在内容中添加换行符?
- reactjs - 如何在赛普拉斯运行的浏览器中使用 process.env 变量
- spring - 来自库/jar文件的spring自动bean定义
- javascript - 压缩数据后如何用Javascript替换图像formdata?