初始化派生类型中的参数

初始化派生类型中的参数

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

问题描述

我仍然用"面向对象"的风格来环绕Fortran.

I am still wrapping my head around Fortran with an "object oriented" flavor.

是否可以将变量初始化为派生类型,如果我希望该变量为parameter怎么办?

Is it possible to initialize a variable in a derived type, and what if I'd like that variable to be a parameter?

例如,经典的animalcatbee类型集应设置每只动物的腿数:

For example, a classic animal, cat, bee set of types that should set the number of legs of each animal:

动物模块

module animal_module
    implicit none

    type, abstract :: animal
        private
        integer, public :: nlegs = -1
    contains
...

cat模块

module cat_module
    use animal_module, only : animal
    implicit none

    type, extends(animal) :: cat
        private
        ! error here about redefining nlegs...
        integer, public :: nlegs = 4
...

我在网上找到了关键字initial,但是我的编译器(英特尔)抱怨该关键字存在语法错误.

I've found online the keyword initial, but my compiler (Intel) complains about the keyword with a syntax error.

我尝试了自定义构造函数,但显然我无法为派生类型写一个.这是我的尝试,仅对 cat 类型:

I've tried a custom constructor but apparently I am unable to write one for derived types. This is my attempt, only on the cat type:

module cat_module
    use animal_module, only : animal
    implicit none

    type, extends(animal) :: cat
        private
        real :: hidden = 23.
    contains
        procedure :: setlegs => setlegs
        procedure :: speak
    end type cat

    interface cat
        module procedure init_cat
    end interface cat

contains

    type(cat) function init_cat(this)
        class(cat), intent(inout) :: this
        this%nlegs = -4
    end function init_cat
...

program oo
    use animal_module
    use cat_module
    use bee_module
    implicit none

    character(len = 3) :: what = "cat"
    class(animal), allocatable :: q

    select case(what)
    case("cat")
        print *, "you will see a cat"
        allocate(cat :: q)
...
    print *, "this animal has ", q%legs(), " legs."

由于animal类型具有integer, public :: nlegs = -1,我希望cat具有-4支脚,但是,可惜它仍然是-1.

As the animal type has integer, public :: nlegs = -1, I expected the cat to have -4 legs, but alas, it's still -1.

推荐答案

不可能命名常量.同样,不可能声明一个抽象类型的组件,然后在扩展类型中为其值定义默认的初始化.尝试使用默认初始化重新声明该组件会导致出现问题.

It is not possible for a component to be a named constant. Also, it isn't possible to declare a component of an abstract type and then define default initialization for its value in an extending type. Attempting to redeclare the component with default initialization leads to the error of the question.

High Performance Mark的评论提供了一条途径:每个扩展类型的自定义构造函数.您可以进一步将组件设置为私有,以进行封装或保护.

High Performance Mark's comment offers one route: provide a custom constructor for each extending type setting the value appropriately. You can further set the component to private for encapsulation or protection.

或者,您可以提供一个"getter"类型绑定过程,该过程引用一个命名常量:

Alternatively, you can provide a "getter" type-bound procedure which references a named constant:

module animal_module
  implicit none

  type, abstract :: animal
   contains
     procedure(getter), deferred :: nlegs
  end type animal

  abstract interface
     integer function getter(creature)
       import animal
       class(animal) creature
     end function getter
  end interface

end module animal_module

module cat_module
  use animal_module, only : animal
  implicit none

  type, extends(animal) :: cat
   contains
     procedure :: nlegs => nlegs_cat
  end type cat

contains

  integer function  nlegs_cat(creature)
    class(cat) creature
    integer, parameter :: my_cat_has_legs=3
    nlegs_cat = my_cat_has_legs
  end function nlegs_cat

end module cat_module

  use cat_module
  implicit none

  class(animal), allocatable :: fido

  fido = cat()
  print*, "Fido has", fido%nlegs(), "legs"
end

最后,initial不是标准的Fortran (并且会有类似的问题).

Finally, initial is not standard Fortran (and would have similar problems).

这篇关于初始化派生类型中的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 09:15