Reputation: 1470
Sorry, me again!
Even though I'm getting better with OOP in Fortran (which is probably the craziest thing I've ever worked with), I have difficulties with inheritance. Unfortunately I do not understand the syntax which allows me to do that.
Basically, what I want to do is override the assignment operator =
which allows me to return any primitive type. A basic example with only one primitive type (real) would look like this:
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
This works when compiling with GNU Fortran (not with Intel as they permit intrinsic assignment overloading). So my question is now how would I define a parent class in a separate module which contains all the assignment overloads (real, integer, character, logical) and use this overrides in a child class which only contains func
? In the program I only want to include the child class and assign the value with something like:
type(child_class) :: child
real :: var
var = child%func('real')
Any help appreciated!
Upvotes: 0
Views: 269
Reputation: 1470
As no one seems to know the answer and I have no clue how to work it out with types I post this "workaround" here in case someone has the same problem. I simply put the assignment overload into a separate module and use the module wherever I need it. A simplified example looks like this:
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
I use this to extract parameters of unknown primitive type from a file (json).
Upvotes: 1