I have a sample following code in which I am trying to test whether a certain object is extended from an abstract derived type.
Here is the module:
module my_module
implicit none
! Abstract parent type
type, abstract :: abstract_parent
integer :: common_member
end type abstract_parent
! Derived type
type, extends(abstract_parent) :: derived_type
real :: additional_member
end type derived_type
! Derived type
type, abstract, extends(abstract_parent) :: special_type
real :: special_member
end type special_type
type, extends(special_type) :: special_derived_type
real :: additional_member
end type special_derived_type
end module my_module
Here is the program:
program main
use my_module
type(derived_type) :: obj1
type(special_derived_type) :: obj2
select type(obj2)
type is(special_type)
write(*,*) "found a special derived type"
end select
end program main
I get an error during compilation with gfortran 13.2.0
33 | type is(special_type)
| 1
Error: Derived type ‘special_type’ at (1) may not be ABSTRACT
I just wanted to check, is there any way to do this (hopefully without sending them to interface procedure rules)? Or is it not easily possible to check what types a variable extends from?
Thanks, @FortranFan. That does exactly what I need.
(A note mostly for my future self). This did not work immediately on my example. It works exactly how I want as long as the initial objects are set up as allocatable classes of the abstract type and then later initialised/allocated with their respective derived types.
@nedanator , have you reviewed any material on the object-oriented aspects of Fortran, say in a reference book such as Modern Fortran Explained covering Fortran 2018? If you have not, I suggest doing so first.
I think the “selector” item (the argument in select type (...)) must be polymorphic (= declared with class), rather than a variable of concrete type declared with type (which we already know its concrete type in that routine!).
Just for fun, it may be interesting to play with this kind of routine by commenting or uncommenting some blocks in select type, or changing the order of blocks, etc, etc.
module my_module2
use my_module
implicit none
contains
subroutine check_type( x )
class(*), intent(in) :: x
select type ( x )
type is ( derived_type )
print *, "concrete type of x = derived_type"
!! type is ( special_derived_type )
!! print *, "concrete type of x = special_derived_type"
class is ( abstract_parent )
print *, "concrete type of x <= abstract_parent"
class is ( special_type )
print *, "concrete type of x <= special_type"
class default; print *, "no match!!"
end select
end subroutine
end module
program main
use my_module2
implicit none
type(derived_type) :: d
type(special_derived_type) :: sd
call check_type( d )
call check_type( sd )
end
Hi @FortranFan. No, not really. I’ve been using and implementing object-oriented things in Fortran for about the past two months (and derived types for around 5 years) and, in that time, I have been reading documentation such as this website and other references like Intel’s webpages when I can find time. I’ve always had trouble with learning things from reading books, I find that I much more need to apply things to a project/task I am interested/passionate in to absorb the information. However, I will see if I can buy the book you recommend and will try and learn from it. Thank you for the recommendation, I greatly appreciate it.
Is this the book you are referring to: “Modern Fortran Explained: Incorporating Fortran 2018 (Numerical Mathematics and Scientific Computation)” by Michael Metcalf?
The section on object-oriented programming and the preceding (and related) section on procedure pointers are only about 35 pages and they can be a very quick read.
The suggestion to review that book, which is authored more as a reference, is not meant as a substitute for the coding exercises and trying things out with a project/task in mind, as you are doing rightly. Rather, it is so that you can ground yourself reasonably well with a good overview of the syntax and semantics of the language that will then give you far more informed direction toward your exercises.
Note there are aspects to modern Fortran which are not intuitive, moreover compilers vary greatly in their robustness. This makes a book such as Modern Fortran Explained a handy reference.
Thanks again for your thorough answer, @FortranFan. Seems like I definitely need to get my hands on it to help with me developing my Fortran skills. Grounding myself in good practices and having a good understanding of the syntax would definitely help prevent me from falling into bad habits or any pitfalls.
Yeah, there are some aspects that don’t, at first, make sense for object-oriented things in Fortran, and the compilers definitely seem extremely variable in what they support (as also seems regularly mentioned on this discourse).