首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Fortran中使用多态数据类型作为另一个数据类型的属性

如何在Fortran中使用多态数据类型作为另一个数据类型的属性
EN

Stack Overflow用户
提问于 2019-08-05 04:28:34
回答 1查看 25关注 0票数 0

我已经创建了一个名为'element‘的类,它有几个属性和类型绑定过程。其中一个属性是抽象类类型'kin‘,它有两个继承类型'kin1’和'kin2‘。我希望能够在运行时根据输入使用构造函数将'kin1‘或'kin2’作为属性分配给对象'element‘。我们的目标是有一个元素列表,每个元素%kin的元素不是'kin1‘类型就是'kin2’类型。

模块元素

模块元素

使用kin

代码语言:javascript
复制
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 

包含

代码语言:javascript
复制
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隐式非私有

代码语言:javascript
复制
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

包含

代码语言:javascript
复制
! 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 

好了!其他程序...

结束模块外观

程序

程序测试

代码语言:javascript
复制
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:分段故障-无效内存引用。

EN

回答 1

Stack Overflow用户

发布于 2019-08-08 20:06:50

我还不能评论,所以这里是第一个答案:不幸的是,所提供的代码是不完整的。此外,缺少编译器的供应商和版本,这使得我们很难猜测真正的问题是什么。

“修复”代码以获得以下示例,表明它在原则上是有效的:

kin.f90:

代码语言:javascript
复制
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

element.f90:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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构建它并运行它会产生以下结果:

代码语言:javascript
复制
$ gfortran -o prog kin.f90 element.f90 main.f90
$ ./prog 
           1
$

与所提供的不同之处在于抽象类型上的延迟print过程,因为它是通过定义为class(kin_type)的属性调用的。不幸的是,这并不能解释引用的错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57350015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档