PVitt
PVitt

Reputation: 11760

Type extensions forth and back

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

Answers (1)

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

Related Questions