I originally posted this question on Stackoverflow (http://stackoverflow.com/questions/30823756/invoking-constructor-of-abst...), but perhaps the Intel community har more knowledge on this topic?
Consider one of the classic OOP examples (see source code at the end of the post):
- Abstract base class Shape
- Class Rectangle extending Shape
I have two questions:
- In the source code below I've tried to define a constructor for the abstract class Shape using class(Shape), pointer :: this as result without ever allocating the pointer. Is this the correct way of defining a constructor for an abstract class in Fortran?
- How can I invoke the constructor of the base class (Shape) in the constructor of the extending class (Rectangle)? Using this%Shape = Shape(xCenter, yCenter) works for non-abstract base classes, but both the Intel compiler and gfortran gives me errors when the result type is class(Shape), pointer (required for an abstract class).
module Shape_mod implicit none private public Shape type, abstract :: Shape private double precision :: centerPoint(2) contains procedure :: getCenterPoint procedure(getArea), deferred :: getArea end type Shape interface Shape module procedure constructor end interface Shape abstract interface function getArea(this) result(area) import class(Shape), intent(in) :: this double precision :: area end function getArea end interface contains !Correct way of defining a constructor for an abstract class? function constructor(xCenter, yCenter) result(this) class(Shape), pointer :: this double precision, intent(in) :: xCenter double precision, intent(in) :: yCenter print *, "constructing base shape" this%centerPoint = [xCenter, yCenter] end function constructor function getCenterPoint(this) result(point) class(Shape), intent(in) :: this double precision point(2) point = this%centerPoint end function getCenterPoint end module Shape_mod module Rectangle_mod use Shape_mod implicit none private public Rectangle type, extends(Shape) :: Rectangle private double precision :: length double precision :: width contains procedure :: getArea end type Rectangle interface Rectangle module procedure constructor end interface Rectangle contains function constructor(length, width, xCenter, yCenter) result(this) type(Rectangle), pointer :: this double precision :: length double precision :: width double precision :: xCenter double precision :: yCenter print *, "Constructing rectangle" allocate(this) this%length = length this%width = width !How to invoke the base class constructor here? !The line below works for non-abstract base classes where the !constructor result can be type(Shape) this%Shape = Shape(xCenter, yCenter) end function constructor function getArea(this) result(area) class(Rectangle), intent(in) :: this double precision :: area area = this%length * this%width end function getArea end module Rectangle_mod program main use Rectangle_mod implicit none type(Rectangle) :: r r = Rectangle(4.0d0, 3.0d0, 0.0d0, 2.0d0) print *, "Rectangle with center point", r%getCenterPoint(), " has area ", r%getArea() end program main