Фортран, эквивалентный чисто виртуальному методу C ++ - PullRequest
3 голосов
/ 31 мая 2019

В C ++ я могу определить общий интерфейс с помощью

class super_class {
public:
    virtual void method()=0;
};

class sub_class : public super_class {
public:
    void method() {
        // Do Something
    }
};

main() {
    super_class *a = new sub_class();
    a->method() // This will call the method defined in the sub_class.
}

Как мне сделать то же самое в Fortran?Я попытался

MODULE super_class
TYPE, ABSTRACT :: super_class_type
END TYPE
END MODULE

MODULE sub_class
TYPE, EXTENDS(super_class_type) :: sub_class_type
CONTAINS
   PROCEDURE :: method
END TYPE

INTERFACE subclass_type
    MODULE PROCEDURE construct_subclass_type
END INTERFACE

CONTAINS

FUNCTION construct_subclass_type()
CLASS (subclass_type), POINTER :: construct_subclass_type
ALLOCATE(construct_subclass_type)
END FUNCTION

SUBROUTINE method(this)
CLASS (sub_class), INTENT(in) :: this
!  Do Something
END SUBROUTINE

END MODULE

PROGRAM example
CLASS (super_class_type), POINTER :: a

a=>construct_subclass_type()
CALL a%method()

END PROGRAM

, но в результате я получил ошибку компилятора.

CALL a%method(3)
       1
Error: ‘method’ at (1) is not a member of the ‘super_class_type’ structure

Я не уверен, как указать, что super_class ожидает, что метод будет переопределен методом подкласса..

Пробовал с использованием отложенного.

Я попытался указать метод как отложенный в суперклассе

TYPE, ABSTRACT :: super_class_type
CONTAINS
    PROCEDURE, DEFERRED :: method
END TYPE

ABSTRACT INTERFACE
    SUBROUTINE method(this)
        CLASS (super_class_type), INTENT(inout) :: this
    END SUBROUTINE
END INTERFACE

, но это вызывает новую ошибку

PROCEDURE, DEFERRED :: method
                  1
Error: Interface must be specified for DEFERRED binding at (1)

CLASS (super_class_type), INTENT(inout) :: this
                       1
Error: Derived type ‘super_class_type’ at (1) is being used before it is defined

1 Ответ

2 голосов
/ 31 мая 2019

Очень просто исправить свой последний код

TYPE, ABSTRACT :: super_class_type
CONTAINS
    PROCEDURE(method_interface), DEFERRED :: method
END TYPE

ABSTRACT INTERFACE
    SUBROUTINE method_interface(this)
        import
        CLASS (super_class_type), INTENT(inout) :: this
    END SUBROUTINE
END INTERFACE


end

Не следует путать название привязки и имя интерфейса. Я переименовал интерфейс, чтобы было понятно. Обратите внимание на оператор import, необходимый для получения локально определенных имен в интерфейсе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...