[RFC] Constructor patch
Tobias Burnus
burnus@net-b.de
Wed Oct 27 14:54:00 GMT 2010
On 10/27/2010 03:26 PM, Jerry DeLisle wrote:
> Just a general question. I think of an OOP constructor has being
> called when an object is instantiated. Here you have a type and not a
> class. What is the value of x if the assignment is not made below? I
> assume -1. Does Fortran have the OOP like constructor I am thinking
> of? (obviously I need to do some more reading)
First, regarding the value without constructor: If the variable is
allocatable, the status is simply unallocated. If it is not allocatable
(nor a pointer), the value for derived types is given by the default
initializer. If a variable is not (default) initialized, the value is
undefined and may not be used.
That's standard Fortran 90/95/2003 - nothing special involved. Also
using a "constructor" of the form:
TYPE t
integer :: i, k
integer :: j = 8 ! default initializer
END TYPE
TYPE(t) :: a
a = t(1, k = 5) ! structure constructor
is nothing new nor special. The point is only that
a = t()
can now not only mean that the structure constructor "t()" is called
(using the default initializer or the passed arguments), but that one
can override the structure constructor by a user-defined constructor using:
INTERFACE t
procedure myT
END INTERFACE t
contains
type(t) function myT(...)
As this form overriding is implemented (in the Fortran language) as
generic procedure, it allows as side effect to implement generic
functions such as my function which returned an integer; that's not a
good programming style and it is not a real constructor but formally
valid. (And maybe in special cases useful.)
In order to make fully use of the constructor, one needs Paul's patch;
namely: (Re)allocate on assignment. For instance:
type(dt), allocatable :: a
a = dt() ! Allocated and assigned the value of the 'constructor'
where again "dt" is either the old Fortran 90+ structure constructor or
a generic function with the name "dt" which overrides the structure
constructor.
Fortran 2008 additionally allows polymorphic types for the (re)allocation:
class(dt), allocatable :: a
a = dt()
a = dt_extending_dt()
Thus, both features together allow for the use as constructor as known
from other object oriented languages - even though the way it has been
fitted into the Fortran language differs to other languages.
To recall my C++ knowledge, I went to some web page describing
constructors in C++. In the example, one finds:
class Point {
public:
Point(); // parameterless default constructor
Point(int new_x, int new_y); // constructor with parameters
...
private:
int x;
int y;
};
Point::Point() { // default constructor
x = 0;
y = 0;
}
Point::Point(int new_x, int new_y) { // constructor
x = new_x;
y = new_y;
}
That matches in Fortran:
module m
private :: Point_init
type Point
integer, private :: x = 0 ! default initialization
integer, private :: y = 0 ! default initialization
end type Point
interface Point
procedure Point_init
end interface Point
contains
function Point_init (int x, int y) result(res)
type(Point) :: res
res%x = x
res%y = y
end function Point_init
end module m
And the usage is also quite similar. While in C++ one has:
Point p; // calls our default constructor
Point q(10,20); // calls constructor with parameters
Point* r = new Point(); // calls default constructor
Point s = p; // our default constructor not called.
The Fortran equivalent is:
type(Point) :: p ! Default initializer
type(Point) :: q, s
type(Point), allocatable :: r
q = Point(10,20) ! Calls Point_init function
r = Point() ! Allocates with default initialized values
s = p ! Assigns value of p
Actually, in this example, the Point_init function is pointless
as the normal structure constructor would have done the same.
Tobias
PS: C++ example taken from
http://www.fredosaurus.com/notes-cpp/oop-condestructors/constructors.html
More information about the Fortran
mailing list