发送指向多态/派生类型的指针

huangapple go评论45阅读模式
英文:

Sending a pointer to a polymorphic/derived type

问题

我遇到了以下的原理性问题:

  • 一个基类(定义为普通类型),我们称之为base_a,它定义了一个通用函数
  • 一个派生类型,我们称之为class_a,它继承自base_a并实现了该通用函数
  • 还有一个通用类,我们称之为class_b(请参阅下面的原理性代码)

我的代码将class base_a 保存为 "type(base_a), pointer"。
我想将这个特定类型发送给通用类(class_b),并将其作为base_a的指针组件 "保存",因为将来我将有其他类继承自base_a,并且我希望将它们也传递给class_b,或者传递给class_b而不是class_a。

在其他编程语言中,这应该是很简单的,因为class_a base_a,而base_a保存在class_b中,因此我可以在class_b中创建一个接收的函数。但是在Fortran中,我似乎无法将class_a作为指针传递,我可能感到困惑,因为所有的 "type"、"class" 和 "pointer" 定义。如果我从Set_class函数(下面)中删除指针,它确实可以工作。

我能在现代Fortran中实现这种行为吗?这真的是我想要的吗?也许我不需要指针...

我要注意的是,我希望尽可能避免让class_b熟悉class_a(因为一旦我不断添加类似于class_a的类型,将它们包括在class_b中将会很痛苦)

以下是代码示例:

type, public :: base_a
contains
    procedure, public :: Write1
...

type, public, extends(base_a) :: class_a
contains
    procedure, public :: Write1 => Write_a
...

type, public :: class_b
    type(base_a), pointer :: really_class_a

contains
    procedure, public :: Set_class
...

subroutine Set_class(this, some_class)
    type(class_b), intent(inout) :: this
    type(base_a), pointer(inout) :: some_class

    this%really_class_a => some_class
end subroutine Set_class

... 在主程序的某处
type(class_a), pointer :: class_a
type(class_b), pointer :: class_b
...
call this%class_b%Set_class(class_a)

我正在使用Intel oneAPI。

我尝试设置以下代码,但它无法编译,当我尝试调用函数Set_class时失败,如果我将参数更改为不带指针,则可以工作。

英文:

I'm encountering the following schematic problem:

  • A base class (defined as a regular type), let's call it base_a that defines a generic function
  • A derived type, let's call it class_a that inherits from base_a and implements that generic function
  • And generic class, let's call it class_b (see schematic code below)

My code saves the class base_a as a "type(base_a), pointer".
I want to send this specific type to the generic class (class_b) and "save" it as a pointer component of base_a --- because in the future I will have other classes inheriting from base_a and i will want to pass them also to class_b, or pass them to class_b instead of class_a.

In other languages its suppose to be straightforward because class_a is base_a and base_a is saved in class_b, therefore i can create a function in class_b that recieves. But in Fortran I can't seem to pass class_a as a pointer, I may be confused because all of the 'type' and 'class' and 'pointer' definitions. It does work if I remove the pointer from Set_class function (below).

Can i even achieve this behavior in Modern Fortran? Is it even something i want? maybe i don't need pointers...

I will note, that i want to avoid making class_b familiar with class_a as much as possible (because once i keep adding types like class_a it will be pain to include them in class_b)

type, public :: base_a
contains 
    procedure, public :: Write1
...

type, public, extends(base_a) :: class_a
contains 
    procedure, public :: Write1 => Write_a
...


type, public :: class_b
    type(base_a), pointer :: really_class_a

 contains
     procedure, public :: Set_class
 ...

 subroutine Set_class(this, some_class)
      type(class_b), intent(inout) :: this
      type(base_a) , pointer(inout) :: some_class

      this%really_class_a => some_class
 end subroutine Set_class

 ... somewhere in main
 type(class_a), pointer :: class_a
 type(class_b), pointer :: class_b
 ...
 call this%class_b%Set_class(class_a)

Using intel oneAPI

I tried setting the following code but it didn't compile, it fails when i try and class the function Set_class, if i change the argument to be without a pointer it works.,

答案1

得分: 0

我成功找到了问题。

在函数Set_class中,接收对象不应该定义为指针,而应该定义为目标。此外,really_class_a应该被定义为class()而不是type()。经过这些更改,它可以工作了!

英文:

I managed to find the problem.

In the function Set_class, the recieving object should not be defined as pointer, but as a target. In addition, really_class_a should be defined as class() and not type(). After these changes it work!

huangapple
  • 本文由 发表于 2023年1月8日 23:20:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75048943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定