是否可以在fortran中定义多态类方法?

时间:2019-07-05 19:03:25

标签: fortran

在c ++中,可以设置多态抽象接口方法

class parent {
    int i;
    single j;

    void set(int i_value)=0;
    void set(single j_value)=0;
};

class child : parent {
    void set(int value) {
       i = value;
    }
    void set(single value) {
       j = value;
    }
};

int main() {
    parent *p = new child();

    p->set(1);       // This sets the i member to 1
    p->set(2.0);     // This sets the j member to 2.0
}

在此示例中,我声明了将在子类中实现的纯虚拟接口方法集。适当的方法将根据参数的类型运行。

我正在尝试在Fortran 2003中设置相同的内容,但我不知道是否可能。我想重载set方法,以便它选择正确的方法以减少所需的代码量。我尝试过,

MODULE test

TYPE, ABSTRACT :: parent
   INTEGER :: i
   REAL    :: j
CONTAINS
   PROCEDURE(parent_set_i), DEFERRED :: set_i
   PROCEDURE(parent_set_r), DEFERRED :: set_r
   GENERIC                           :: set => set_i, set_r
END TYPE

INTERFACE
   SUBROUTINE parent_set_i(this, value)
      IMPORT
      CLASS (parent), INTENT(inout) :: this
      INTEGER, INTENT(in)          :: value
   END SUBROUTINE

   SUBROUTINE parent_set_r(this, value)
      IMPORT
      CLASS (parent), INTENT(inout) :: this
      REAL, INTENT(in)              :: value
   END SUBROUTINE
END INTERFACE

TYPE, EXTENDS(parent) :: child
CONTAINS
   PROCEDURE(child_set_i) :: set_i
   PROCEDURE(child_set_r) :: set_r
END TYPE

CONTAINS

SUBROUTINE child_set_i(this, value)
   CLASS (child), INTENT(inout) :: this
   INTEGER, INTENT(in)          :: value

   this%i = value

END SUBROUTINE

SUBROUTINE child_set_r(this, value)
   CLASS (child), INTENT(inout) :: this
   REAL, INTENT(in)             :: value

   this%j = value

END SUBROUTINE

END MODULE

PROGRAM example
   USE test

   CLASS (child), POINTER  :: c
   CLASS (parent), POINTER :: p
   ALLOCATE(c)
   p => c
   p%set(1)
   p%set(2.0)

END PROGRAM

但是最终会出现编译错误,指出:

          PROCEDURE(child_set_i) :: set_i
                               1
Error: PROCEDURE(interface) at (1) should be declared DEFERRED

这是否有可能,还是我需要对类方法进行更明确的说明?

1 个答案:

答案 0 :(得分:2)

我不了解C ++,这是您要尝试的吗?

ian-admin@agon ~/work/stack $ cat pai.f90
Module test

  Type, Abstract :: parent
     Integer :: i
     Real    :: j
   Contains
     Procedure(parent_set_i), Deferred :: set_i
     Procedure(parent_set_r), Deferred :: set_r
     Generic                           :: set => set_i, set_r
  End Type parent

  Interface
     Subroutine parent_set_i(this, Value)
       Import
       Class (parent), Intent(inout) :: this
       Integer, Intent(in)          :: Value
     End Subroutine parent_set_i

     Subroutine parent_set_r(this, Value)
       Import
       Class (parent), Intent(inout) :: this
       Real, Intent(in)              :: Value
     End Subroutine parent_set_r
  End Interface

  Type, Extends(parent) :: child
Contains
  Procedure :: set_i => child_set_i
  Procedure :: set_r => child_set_r
End Type

Contains

  Subroutine child_set_i(this, Value)
    Class (child), Intent(inout) :: this
    Integer, Intent(in)          :: Value

    this%i = Value

  End Subroutine child_set_i

  Subroutine child_set_r(this, Value)
    Class (child), Intent(inout) :: this
    Real, Intent(in)             :: Value

    this%j = Value

  End Subroutine child_set_r

End Module test

Program example
  Use test

  Class (child), Pointer  :: c
  Class (parent), Pointer :: p
  Allocate(c)
  p => c
  Call p%set(1)
  Call p%set(2.0)

End Program example
ian-admin@agon ~/work/stack $ gfortran -std=f2008 -Wall -Wextra -fcheck=all pai.f90 
ian-admin@agon ~/work/stack $ ./a.out
ian-admin@agon ~/work/stack $