问题
Suppose I have defined a derived type (in Fortran 2003) named geometry
and I extend it to two new derived types: circle
and triangle
. Each extended type has its own constructor, NewCircle
and NewTriangle
that returns a circle
object and a triangle
object respectively.
Then I would like to do this:
use appropriate_module
class(geometry), allocatable :: Geo(:)
allocate(Geo(2))
Geo(1) = NewCircle
Geo(2) = NewTriangle
Of course the last two lines are invalid in Fortran 2003 standard. I do not want to create an array of pointers encapsulated in a derived type to link object of different type because the objects need to be created before being linked in the array. In the above (hypothetical) case, the objects would be created and stored in the array immediately.
Any suggestion to do it, or is it a limitation of the language?
回答1:
If you want value semantics, create an array of derived type with a polymorphic allocatable component.
use appropriate_module
type geometry_element
class(geometry), allocatable :: item
end type geometry_element
type(geometry_element), allocatable :: geo(:)
geo = [ geometry_element(NewCircle()), &
geometry_element(NewTriangle()) ]
If a new geometry
object was passed back to the calling scope using an allocatable argument (rather than via a function result), then the MOVE_ALLOC
intrinsic provides an efficient way of moving the constructed value into an element of the array.
来源:https://stackoverflow.com/questions/31106539/polymorphism-in-an-array-of-elements