Originally posted by: Rafik_Zurob
One of the main features of Fortran 2003 is object-orientation (OO). Derived types can now have specific and generic type-bound procedures, type-bound defined operators, type-bound defined assignment, type-bound finalizers (destructors), and type-bound user-defined derived type IO routines. For example, type base below has specific type-bound procedures find, assign, add and writef, defined operator +, type bound assignment, and a user-defined derived type IO formatted write routine:
module m
type base
integer, allocatable :: data(:)
contains
procedure :: find
procedure :: assign
procedure :: add
procedure :: writef
generic :: assignment(=) => assign
generic :: operator(+) => add
generic :: write(formatted) => writef
end type
!...
contains
!...
end module
If you're familiar with other OO languages, you might be wondering about constructors. Were they missed in Fortran 2003?
The answer is no. Fortran 2003 has support for default and user-defined constructors. The constructors are not type-bound procedures, however. Structure constructors act as default constructors. User-defined constructors are created by defining a generic interface with the same name as the derived type they're supposed to construct. For example:
module m
!...
interface base
module procedure new_base
end interface
contains
!...
function new_base(i)
integer, intent(in) :: i
type(base) new_base
allocate(new_base%data(i))
new_base%data = i
end function
!...
end module
The interface above defines a user-defined constructor for type base. It is used in a similar way to a structure constructor. It can even take argument keywords.
use m
implicit none
type(base) b1, b2, b3
b1 = base(3) ! calls new_base, assign
print *, b1 ! calls writef
b2 = base(i=4) ! calls new_base, assign
print *, b2 ! calls writef
b3 = b1 + b2 ! calls add, assign
print *, b3 ! calls writef
end
I've attached the full example to the files section as "constructor_example.f". To illustrate the calls, I'll use the functrace feature of the XL Fortran compiler. This feature calls a user-defined routine on entry and exit of every procedure. Default entry and exit routines are provided in the samples/functrace directory of the compiler installation.
For example, on my AIX machine:
> cc -c /usr/lpp/xlf/samples/functrace/tracing_routines.c
> xlf2003 constructor_example.f -qfunctrace tracing_routines.o
* m === End of Compilation 1 ===
** _main === End of Compilation 2 ===
1501-510 Compilation successful for file constructor_example.f.
> ./a.out
{ _main (constructor_example.f:103)
{ __m_NMOD_new_base (constructor_example.f:95)
} __m_NMOD_new_base (constructor_example.f:97)
{ __m_NMOD_assign (constructor_example.f:52)
} __m_NMOD_assign (constructor_example.f:53)
{ _xlfdtioproc0 (constructor_example.f:0)
{ __m_NMOD_writef (constructor_example.f:84)
} __m_NMOD_writef (constructor_example.f:89)
} _xlfdtioproc0 (constructor_example.f:0)
3 3 3
{ __m_NMOD_new_base (constructor_example.f:95)
} __m_NMOD_new_base (constructor_example.f:97)
{ __m_NMOD_assign (constructor_example.f:52)
} __m_NMOD_assign (constructor_example.f:53)
{ _xlfdtioproc0 (constructor_example.f:0)
{ __m_NMOD_writef (constructor_example.f:84)
} __m_NMOD_writef (constructor_example.f:89)
} _xlfdtioproc0 (constructor_example.f:0)
4 4 4 4
{ __m_NMOD_add (constructor_example.f:60)
{ __m_NMOD_assign (constructor_example.f:52)
} __m_NMOD_assign (constructor_example.f:53)
} __m_NMOD_add (constructor_example.f:74)
{ __m_NMOD_assign (constructor_example.f:52)
} __m_NMOD_assign (constructor_example.f:53)
{ _xlfdtioproc0 (constructor_example.f:0)
{ __m_NMOD_writef (constructor_example.f:84)
} __m_NMOD_writef (constructor_example.f:89)
} _xlfdtioproc0 (constructor_example.f:0)
7 7 7 4
} _main (constructor_example.f:109)
>
Notice how new_base above was called for base(3) and base(i=4).