Можно ли определить метод полиморфного класса в фортране? - PullRequest
1 голос
/ 05 июля 2019

В 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 Ответ

2 голосов
/ 05 июля 2019

Я не знаю 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 $ 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...