Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to implement an "abstract" variable inside a type in Fortran 2003?

I would like to write an abstract type

type, abstract :: Vehicle
    real, dimension(:), allocatable:: Wheels 
    contains
     procedure (Compute_Weight), deferred :: VehicleWeight
end type Vehicle

that is I'd like to have a placeholder in the abstract type for an array in such a way that it could be overridden or redefined in the extended type with something like

type, extends(Vehicle) :: Bike
     allocate(Wheels(2))
    contains
     procedure :: VehicleWeight => BikeWeight
end type Bike

    type, extends(Vehicle) :: Car
     allocate(Wheels(4))
    contains
     procedure :: VehicleWeight => CarWeight
end type Car

GCC compiler complains (rightfully I guess), and the onlys solution I could find to this problem is just to not declare the allocatable function in the abstract type and declare the variable directly with the correct size inside the type. Nevertheless I would like to have a sort of placeholder to enforce the implementation of the fundamental property descrived by Wheels (a prototype). I

like image 723
ray Avatar asked Feb 15 '23 23:02

ray


1 Answers

Allocation of an component is an executable action - it needs to appear in an executable part of your source. Consider something like:

type, abstract :: vehicle
  real, dimension(:), allocatable :: wheels
  ...
end type

type, extends(vehicle) :: bike
  ...
end type bike

type, extends(vehicle) :: car
  ...
end type car

interface bike
  procedure bike_constructor
end interface bike

interface car
  procedure car_constructor
end interface car

...

function bike_constructor()
  type(bike) :: bike_constructor
  allocate(bike_constructor%wheels(2))
  ...
end function bike_constructor

function car_constructor()
  type(car) :: car_constructor
  allocate(car_constructor%wheels(4))
  ...
end function car_constructor

In Fortran 2008, this can be used in the following straightforward manner:

class(vehicle), allocatable :: obj
IF (i_feel_like_some_exercise) THEN
  obj = bike()
ELSE
  obj = car()
END IF
PRINT "('My object has ',I0,' wheels!')", SIZE(obj%wheels)

In Fortran 2003, intrinsic assignment to a polymorphic object is not supported. Workarounds such as using a SOURCE specifier in an ALLOCATE statement need to be used.

Appropriate application of public and private to components and procedures can further guide and constrain client code to interact with the types in the right way.

like image 67
IanH Avatar answered Apr 26 '23 12:04

IanH