派生类型的构造方法

sen*_*iwa 5 constructor fortran derived-types

我正在尝试为抽象的派生类型编写一个构造函数,以解决另一个问题,但似乎它没有用,或者更好,根本没有调用。

目的是使运行时多态性设置正确的动物腿数。

这是两个模块:

动物

module animal_module
    implicit none

    type, abstract :: animal
        private
        integer, public :: nlegs = -1
    contains
        procedure :: legs
    end type animal

contains

    function legs(this) result(n)
        class(animal), intent(in) :: this
        integer :: n

        n = this%nlegs
    end function legs
Run Code Online (Sandbox Code Playgroud)

module cat_module
    use animal_module, only : animal
    implicit none

    type, extends(animal) :: cat
        private
    contains
        procedure :: setlegs => setlegs
    end type cat

    interface cat
        module procedure init_cat
    end interface cat

contains

    type(cat) function init_cat(this)
        class(cat), intent(inout) :: this
        print *, "Cat!"
        this%nlegs = -4
    end function init_cat
Run Code Online (Sandbox Code Playgroud)

主程序

program oo
    use animal_module
    use cat_module
    implicit none

    type(cat) :: c
    type(bee) :: b

    character(len = 3) :: what = "cat"

    class(animal), allocatable :: q

    select case(what)
    case("cat")
        print *, "you will see a cat"
        allocate(cat :: q)
        q = cat() ! <----- this line does not change anything

    case default
        print *, "ohnoes, nothing is prepared!"
        stop 1
    end select

    print *, "this animal has ", q%legs(), " legs."
    print *, "cat  animal has ", c%legs(), " legs."
end program
Run Code Online (Sandbox Code Playgroud)

根本没有调用构造函数,并且支路数量仍为-1

fra*_*lus 4

该类型的可用非默认构造函数cat由模块 procedure 给出init_cat。您定义的这个函数如下

type(cat) function init_cat(this)
    class(cat), intent(inout) :: this
end function init_cat
Run Code Online (Sandbox Code Playgroud)

它是一个只有一个参数的函数,为class(cat)。在你以后的参考中

q = cat()
Run Code Online (Sandbox Code Playgroud)

泛型下没有cat与该引用匹配的特定函数:该函数init_cat不接受无参数引用。相反,使用默认的结构构造函数。

cat您必须以与您的接口匹配的方式引用泛型init_cat才能调用该特定函数。

你想改变你的init_cat功能看起来像

type(cat) function init_cat()
    ! print*, "Making a cat"
    init_cat%nlegs = -4
end function init_cat
Run Code Online (Sandbox Code Playgroud)

然后就可以根据q=cat()需要参考了。

请注意,在原文中,您正在尝试“构造”一个cat​​实例,但您不会将此构造的实体作为函数结果返回。相反,您正在修改一个参数(已经构造)。结构构造函数旨在返回此类有用的东西。

另请注意,您不需要

allocate (cat :: q)
q = cat()
Run Code Online (Sandbox Code Playgroud)

对 的内在分配q已经处理了q的分配。