派生类型的构造方法 [英] Constructor of derived types

查看:116
本文介绍了派生类型的构造方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为派生的类型的抽象类型编写构造函数,以

I am trying to write a constructor for a derived type of an abstract one to solve this other question, but it seems that it's not working, or better, it isn't called at all.

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

The aim is to have a runtime polymorphism setting the correct number of legs of an animal.

这是两个模块:

动物

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

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

主程序

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

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

The constructor isn't called at all, and the number of legs still remains to -1.

推荐答案

cat类型的可用非默认构造函数由模块过程init_cat给出.您定义的功能类似

The available non-default constructor for the cat type is given by the module procedure init_cat. This function you have defined like

type(cat) function init_cat(this)
    class(cat), intent(inout) :: this
end function init_cat

它是一个带有class(cat)参数的函数.在以后的参考中

It is a function with one argument, of class(cat). In your later reference

q = cat()

在通用cat下没有与该引用匹配的特定功能:函数init_cat不接受无参数引用.而是使用默认的结构构造函数.

There is no specific function under the generic cat which matches that reference: the function init_cat does not accept a no-argument reference. The default structure constructor is instead used.

您必须以与init_cat接口匹配的方式引用通用cat,以调用该特定功能.

You must reference the generic cat in a way matching your init_cat interface to have that specific function called.

您要更改init_cat函数的外观

type(cat) function init_cat()
    ! print*, "Making a cat"
    init_cat%nlegs = -4
end function init_cat

然后您可以根据需要引用q=cat().

Then you can reference q=cat() as desired.

请注意,在原始版本中,您试图构造" cat实例,但是没有返回此构造的实体作为函数结果.相反,您正在修改参数(已经构造).打算使用结构构造函数返回这些有用的东西.

Note that in the original, you are attempting to "construct" a cat instance, but you aren't returning this constructed entity as the function result. Instead, you are modifying an argument (already constructed). Structure constructors are intended to be used returning such useful things.

请注意,您不需要

allocate (cat :: q)
q = cat()

q的固有分配已经处理了q的分配.

The intrinsic assignment to q already handles q's allocation.

这篇关于派生类型的构造方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆