在每个数据类型实例中复制过程

时间:2014-02-15 23:25:25

标签: oop fortran fortran2003

当我们从具有传递过程指针的数据类型(类)创建多个实例时,是否在每个实例中复制了实际的过程(子例程/函数)?或只是复制指针?

例如,请考虑以下编译和运行正确的代码。

module mod2
  implicit none

  private

  type class_type
     integer :: a, b, c
   contains
     procedure :: add => add_it
  end type class_type

  public :: class_type

contains

  subroutine add_it(this)
    implicit none
    class(class_type), intent(inout) :: this

    this%c = this%a + this%b

  end subroutine add_it

end module mod2

program tester
  use mod2
  implicit none

  type(class_type), dimension(10) :: objs

  objs(:) = class_type(1, 2, 0)

end program tester

从数据类型add_it创建的10个对象中的每个对象中是否重复了子例程class_type?或者是存储在某处的子程序add_it的指令集以及指向它的指针,即在每个对象中复制了"procedure :: add => add_it"

1 个答案:

答案 0 :(得分:1)

通常都不是。请注意,这是非常具体的实现 - 我在下面描述的是典型的,但不同的处理器可能会做不同的事情。

请注意,示例中没有过程指针。类型class_type具有绑定。如果class_type有一个过程指针,则情况就不同了。

绑定的典型实现是编译器创建一个机器级指针表,每个特定绑定有一个条目,指针指向过程的代码。为程序中的每种类型创建一个表(有时称为“vtable”,来自用于C ++和类似语言中的虚拟成员函数的类似技术)。

对于多态对象(用CLASS声明的事物),编译器然后创建一个描述符,该描述符具有指向对象的动态(运行时)类型的相关表的机器级指针。此指针有效指示对象的动态类型,可用于SELECT TYPE等构造以及SAME_TYPE_AS之类的调用。如果你有一个多态数组,编译器最初通常只为整个数组创建一个描述符,因为数组中的各个元素必须都具有相同的动态类型。

当您对多态对象调用绑定时,编译器会跟随指向vtable的指针,然后查找指向过程绑定的相关指针。

非多态对象(使用TYPE声明的事物)不需要这样的描述符或指针解引用,因为动态和声明的类型总是相同的,编译器在编译时知道声明的类型是什么并且编译器知道将调用哪个程序。

如果您有一个过程调用,其中非多态实际参数与多态伪参数相关联,那么编译器通常会创建必要的描述符作为进行过程调用的一部分。类似地,将多态数组元素传递给采用多态标量的过程。

您的代码的主程序不包含多态实体,并且您不调用任何过程,因此可能没有任何机器指针返回到vtable。

过程指针组件(在类型声明的CONTAINS之前声明为PROCEDURE(xxx), POINTER :: yyy的组件)对于每个对象可以是不同的(包括对于数组中的每个元素都不同)。在这种情况下,典型的实现是将机器级指针存储到相关过程的代码(如果过程指针组件尚未关联,则为空指针)。