Reputation: 11760
I have a base library with is used by two different applications. We changed some stuff in the base library recently and are now adapting the applications to this change. Today I stumbled over some code that smells like a good idea to do it in an object oriented way, but the more I think about it, the less I think Fortrans OO-features are capable of this.
But in detail: We have a routine that operates on a type and uses one if it's properties. Lets call it container:
type element
integer :: id
end type element
type container
type(element), allocatable :: elements(:)
end type container
Each application is now able to extend this type:
type, extends(container) :: myContainer
!...
end type myContainer
Until here everything is pretty fine. But one if the application needs to extend the element
type as well:
type, extends(elemet) :: myElement
integer :: someOtherStuff
end type myEement
When I got everthing right, it is possible to add instances of myElement
to myContainer%elemets
, at least using myElement%element
. But is it also possible to get the original instance out of myContainer%element
?
Consider the following code:
type(myElement) :: element, after
type(myContainer) :: container
allocate(myContainer%elements(1))
!will result in Can't convert TYPE(myElement) to TYPE(element)
!myContainer%elements(1) = element
myContainer%elements(1) = element%element
! vice versa from above
!after = myContainer%elements(1)
after%element = myContainer%elements(1)
I could assign the element from the list to after%element
, but all data specific to myElement wouldn't be set. I guess the data is already lost when assigning element%element
to the list? So is there any way to achieve some kind of type preservation in Fortran which would also preserve the information of myElement
even when adressing it's instance as element
?
In other languages, e.g. C# you can assign a subclass to a collection of superclasses, get the instance back and use it as a subclass again, because the complete object was stored in the collection and it was just addressed as an instance of the superclass. When addressed as a subclass again, it still contains all information it had before it was added to the collection.
Is there something similar in Fortran?
Upvotes: 1
Views: 66
Reputation: 60008
You can make the container be able to contain a polymorphic value
type container
class(element), allocatable :: elements(:)
end type container
then you can allocate the array elements
to a type which is extended from element
.
When you just assign element%element
you only copy a part of the extended type which corresponds to the base type.
Upvotes: 3