- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to use pointers to create links between objects. Using Fortran and here is the code piece:
module base_pars_module
type,abstract,public :: base_pars
end type
end module
module test_parameters_module
use base_pars_module
type, extends(base_pars) :: test_pars
contains
procedure :: whoami
end type
contains
function whoami(this) result(iostat)
class( test_pars) :: this
write(*,*) 'i am a derived type child of base_pars'
end type
end module
module base_mask_module
use base_pars module
type, abstract , public :: base_mask
class(base_pars),pointer :: parameters
end type
end module
module test_mask_module
use base_mask_module
implicit none
type, extends(base_mask) :: test_mask
end type
end module
program driver
type(test_pars) , target :: par_Test
type(test_mask) :: mask_test
iostat= par_test%whoami()
mask_test%parameters=>par_test
iostat=mask_test%parameters%whoami()
end program
parameters
at base_mask_module
is a pointer with base_pars
class. I would like to use this pointer to refer par_test
object which is test_pars
type that extends base_pars
type. So the pointer and the target has the same class. But when I compile this it gives an error:
driver.f90:17.37:
iostat=mask_test%parameters%whoami()
1
Error: 'whoami' at (1) is not a member of the 'base_pars' structure
Is it a bug or am i doing something wrong?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Look into "SELECT TYPE" construct: you need it to unmask the polymorphic object and invoke the methods associated with it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your question has already been answered by others at http://stackoverflow.com/questions/31220961/fortran-polymorphism-in-pointers
The error message is valid and a reasonable summary of the problem with the code. `mask_test%parameters` is of type `base_pars`, and that type does not have a binding `whoami`. The presence of a binding of that name in types that are extensions of `base_pars` is not relevant - in a statically typed language, such as Fortran (and many others), the available set of bindings and components are determined by the declared type of an object, not its dynamic type.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know that answers in the StackoverFlow but wanted to port the discussion here.
My problem in fact is this. I want to create objects from two different abstract classes.
Lets say base_a and base_b
And I want to create objects from classes class_a which is child of base_a and class_b child of base_b.
And , I want to establish a connection between child_a and child_b in terms of pointers at the abstract type definition while I am defining base_a and base_b. I want a pointer which points from base_a to any objects which inherits base_b.
I think this is not possible with fortran. If it is I don't know how. I discussed this with a computer engineer, expert in Java. He says it is quite possible to do this with java. As far as I understand, pointers in Fortran are not as polymorphic as pointers of other languages.
So is there any work-around for this?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In Fortran, a polymorphic pointer can point at any object that is of a type that is an extension of the type of the pointer (i.e. the type of the pointer and any types that ultimate EXTEND the type of the pointer). This is exactly what you do in the line before the line that incurs an error message from the compiler.
The error above does not arise because you cannot point the polymorphic pointer at an object - it arises because the type of the pointer is that of the abstract parent type, and that abstract parent type does not have the member that you request.
I am not a java programmer (which is an understatement), but here is the naive transliteration of your example into java. It fails with a similar error to the Fortran program, for similar reasons. If I change the type of the member reference to be that of the `test_pars` extension - the error message goes away - as it would if you did the same in Fortran.
Perhaps you can discuss this example with your java expert. If their response involves using a type cast, to downcast the `mask_test.parameters` reference to a base_pars object to be a reference to a test_pars object, then that is equivalent to using SELECT TYPE in Fortran, as others have suggested.
class ExampleApp { class base_pars { } class test_pars extends base_pars { public int WhoAmI() { System.out.println("I am a test_pars - a subclass of base_pars"); return 0; } } class base_mask { public base_pars parameters; /* public test_pars parameters; */ } class test_mask extends base_mask { } public static void main(String[] args) { try { ExampleApp obj = new ExampleApp(); obj.run(args); } catch (Exception e) { e.printStackTrace(); } } void run(String[] args) { test_pars par_Test = new test_pars(); test_mask mask_test = new test_mask(); mask_test.parameters = par_Test; int iostat = mask_test.parameters.WhoAmI(); } }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
dundar11 wrote:
.. . I discussed this with a computer engineer, expert in Java. He says it is quite possible to do this with java. As far as I understand, pointers in Fortran are not as polymorphic as pointers of other languages. ..
So why don't you ask this Java expert to give you a minimal working example of what you want to do in Java without using type casting? And why don't you post the Java example here? We can then offer comments on what is possible with Fortran. But I'm willing to bet the "expert in Java" has type casting in mind which, as IanH pointed out, is the same as using SELECT TYPE in Fortran. One may argue there is "syntactic sugar" available in Java with type casting that allows a coder to accomplish the same task in fewer keystrokes compared to, say, Fortran. But that would be a separate discussion altogether.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That java part was a misunderstanding between me and my friend. However is it possible to "cast" type of the pointer?
In the initial example
class(base_pars),pointer :: parameters
Pointer parameters belongs to base_pars class. What if I allocate this pointer at the body of the program:
allocate(test_pars::mask_test%parameters)
and point this to par_Test?
mask_test%parameters=>par_test
and call the function whoami later:
iostat=mask_test%parameters%whoami()
It still gives the compiler error. says whoami does not belong to base_pars class. However I should be able to cast this pointer with test_pars type. If not what is the point of using classes?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
dundar11 wrote:
That java part was a misunderstanding between me and my friend. However is it possible to "cast" type of the pointer?
In the initial example
class(base_pars),pointer :: parametersPointer parameters belongs to base_pars class. What if I allocate this pointer at the body of the program:
allocate(test_pars::mask_test%parameters)
and point this to par_Test?
mask_test%parameters=>par_test
and call the function whoami later:
iostat=mask_test%parameters%whoami()
It still gives the compiler error. says whoami does not belong to base_pars class. However I should be able to cast this pointer with test_pars type. If not what is the point of using classes?
No, you would still need to use "SELECT TYPE" construct to unmask the polymorphic object. Or if the base_pars class design is something you have control over, you can redesign it as suggested to you on the StackOverflow forum.
Re: "what is the point of using classes?", you can best answer this question for yourself by (re)reading the books/articles on object-oriented programming applications in Fortran e.g., https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world and http://www.hindawi.com/journals/sp/2015/942059/

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page