Наследовать назначение из родительского класса в Фортране - PullRequest
0 голосов
/ 09 октября 2018

Извините, я снова!

Несмотря на то, что мне становится лучше с ООП в Фортране (что, вероятно, самая безумная вещь, с которой я когда-либо работал), у меня возникают трудности с наследованием.К сожалению, я не понимаю синтаксис, который позволяет мне это делать.

По сути, я хочу переопределить оператор присваивания =, который позволяет мне возвращать любой тип примитива .Базовый пример только с одним типом примитива (реальный) будет выглядеть следующим образом:

module overload

    implicit none

    public func, assignment(=)

    interface assignment(=)
        module procedure equalAssignmentReal
        !! additional procedures for integer, character, logical if neccessary
    end interface

contains

    subroutine equalAssignmentReal(lhs, rhs)      !! <-- all these subroutines should be in the parent class

        implicit none

        real,     intent(out) :: lhs
        class(*), intent(in)  :: rhs

        select type(rhs)
            type is (real)
                lhs = rhs
        end select

        return

    end subroutine equalAssignmentReal

    function func(string) result(res)      !! <-- I want this function in the child class

        implicit none

        character(len=*), intent(in) :: string
        class(*), allocatable        :: res

        if (  string == "real" ) allocate(res, source=1.0)

        return

    end function func

end module overload

program test

    use overload

    implicit none

    real :: var

    var = func('real')

    print *, "var = ", var

end program test

Это работает при компиляции с GNU Fortran (не с Intel, поскольку ониразрешить внутреннюю перегрузку присваивания).Итак, мой вопрос теперь состоит в том, как бы определить родительский класс в отдельном модуле, который содержит все перегрузки присваивания (действительные, целые, символьные, логические) и использовать эти переопределения в дочернем классе который содержит только func?В программу я только хочу включить дочерний класс и присвоить значение с чем-то вроде:

type(child_class) :: child
real :: var

var = child%func('real')

Любая помощь приветствуется!

1 Ответ

0 голосов
/ 11 октября 2018

Поскольку никто, кажется, не знает ответа, и я понятия не имею, как его решить с типами Я выкладываю этот «обходной путь» здесь на тот случай, если у кого-то возникнет такая же проблема.Я просто помещаю перегрузку назначения в отдельный модуль и использую модуль везде, где мне это нужно.Упрощенный пример выглядит следующим образом:

module overload

    implicit none

    public assignment(=)

    interface assignment(=)
        module procedure equalAssignmentReal
        module procedure equalAssignmentInteger
        !! additional procedures for character, logical if neccessary
    end interface

contains

    subroutine equalAssignmentReal(lhs, rhs)

        implicit none

        real,     intent(out) :: lhs
        class(*), intent(in)  :: rhs

        select type(rhs)
            type is (real)
                lhs = rhs
        end select

        return

    end subroutine equalAssignmentReal

    subroutine equalAssignmentInteger(lhs, rhs)

        implicit none

        integer,  intent(out) :: lhs
        class(*), intent(in)  :: rhs

        select type(rhs)
            type is (integer)
                lhs = rhs
        end select

        return

    end subroutine equalAssignmentInteger

end module overload


module assignment

    implicit none

    public find
    public par1

    real    :: par1
    integer :: par2

contains

    subroutine init

        use overload

        implicit none


        par1 = find('real')
        par2 = find('integer')        

        return

    end subroutine init

    function find(in) result(out)

        implicit none

        character(len=*), intent(in)  :: in
        class(*), allocatable         :: out

        if ( in == 'real' ) then

            allocate(out, source=1.)

        else if ( in == 'integer' ) then

            allocate(out, source=2)

        end if 

        return

    end function find

end module assignment

program test

    use assignment

    implicit none

    call init

    print *, "par1 = ", par1
    print *, "par2 = ", par2

end program test

Я использую это для извлечения параметров неизвестного типа примитива из файла (json).

...