Can anyone please give me an example on how is it supposed to be for a simple Fortran 2003 Object oriented layout equivalent to this C++ code:
stefanos-imac:tmp borini$ more Animal.h
class Animal {
public:
Animal(int age);
~Animal();
virtual void speak();
int getAge();
private:
int age;
};
stefanos-imac:tmp borini$ more Animal.cpp
#include <Animal.h>
#include <iostream>
Animal::Animal(int age) {
std::cout << "init animal" << age << std::endl;
this->age = age;
}
Animal::~Animal() {
std::cout << "dtor animal" << std::endl;
}
void Animal::speak() {
std::cout << "speak not reimplemented" << std::endl;
}
int Animal::getAge() {
return this->age;
}
stefanos-imac:tmp borini$ more Cat.h
#include <Animal.h>
class Cat : public Animal {
public:
Cat(int age);
~Cat();
virtual void speak();
};
stefanos-imac:tmp borini$ more Cat.cpp
#include <Cat.h>
#include <iostream>
Cat::Cat(int age) : Animal(age) {
std::cout << "init cat" << std::endl;
}
Cat::~Cat() {
std::cout << "dtor cat" << std::endl;
}
void Cat::speak() {
std::cout << "meow" << std::endl;
}
stefanos-imac:tmp borini$ more main.cpp
#include <iostream>
#include <Cat.h>
int main() {
Cat c(10);
std::cout << c.getAge() <<std::endl;
c.speak();
}
I am having problems with my code, see the following
stefanos-imac:oop borini$ more Animal.f90
module AnimalModule
implicit none
private
public :: AnimalType
type :: AnimalType
private
integer :: age
contains
procedure :: getAge
procedure :: speak
final :: dtor
end type
interface AnimalType
module procedure ctor
end interface
contains
subroutine ctor(self, age)
type(AnimalType), intent(inout) :: self
integer :: age
print *, "Constructor Animal"
self%age = age
end subroutine
subroutine dtor(self)
type(AnimalType), intent(inout) :: self
print *, "Destroying animal"
end subroutine
function getAge(self)
class(AnimalType), intent(inout) :: self
integer :: getAge
getAge = self%age
end function
subroutine speak(self)
class(AnimalType), intent(in) :: self
print *, "Animal::speak not overridden"
end subroutine
end
stefanos-imac:oop borini$ more Cat.f90
module CatModule
use AnimalModule
implicit none
private
type, extends(AnimalType) :: CatType
private
contains
procedure :: speak
final :: dtor
end type
interface CatType
module procedure ctor
end interface
contains
subroutine ctor(self, age)
type(CatType), intent(inout) :: self
integer, intent(in) :: age
print *, "Constructor Cat"
self%AnimalType = AnimalType(age)
end subroutine
subroutine dtor(self)
type(CatType), intent(inout) :: self
print *, "Destroying Cat"
end subroutine
subroutine speak(self)
class(CatType), intent(in) :: self
print *, "Meow"
end subroutine
end
stefanos-imac:oop borini$ ifort Animal.f90 Cat.f90
Cat.f90(10): error #8341: Final subroutines are not inherited through type extension and cannot be overridden. [DTOR]
final :: dtor
---------------^
Cat.f90(22): error #6292: The parent type of this field is use associated with the PRIVATE fields attribute [AGE]
self%AnimalType = AnimalType(age)
-----------------------------------^
compilation aborted for Cat.f90 (code 1)
stefanos-imac:oop borini$
In particular, it's not clear to me how to initialize the base class, and how to define the destructor for the derived class.
Thanks
subroutine ctor(self, age)
type(CatType), intent(inout) :: self
integer, intent(in) :: age
print *, "Constructor Cat"
self%AnimalType = AnimalType(age)
end subroutine
This is wrong. CatType has no AnimalType component. It extends the AnimalType type. ctor is a subroutine and you use it as a function. I suggest you, to define constructor (but it will be more just initializing, not allocating) as a function, but subroutine can also be used. You can use the interface block as you did to achieve the same name as the class name, but you have to be consistent and use CALL, if you defined it as a subroutine.
In the constructor of the derived class you could just set the right component, or use the constructor of the base class. Do not forget to write right working user defined assignments for your types then.
Related
Let me start stating I'm a self-made programming passionate, so forgive the unprofessional language, not speaking English very well I got support from translator. From what I've understood it seems that casting a pointer to an object and one of its functions member cannot be made to a dummy structure. In particular, the call to the member function cannot be made in this way:
#include <iostream>
struct _T{};
class Class1
{
public:
void print()
{ std::cout << "Class1::print ...." << std::endl; }
int sum(int value)
{ return m_dato+value; }
private:
int m_dato { 10 };
};
int main()
{
Class1 item;
void(_T::*func)();
int(_T::*fsum)(int);
Class1* p1=&item;
auto p2=reinterpret_cast<_T*>(p1);
func =reinterpret_cast<void(_T::*)()>(&Class1::print);
(p2->*func)();
fsum =reinterpret_cast<int(_T::*)(int)>(&Class1::sum);
auto dato=(p2->*fsum)(55);
std::cout << "Dato: " << dato << std::endl; // ok 65..
std::cout << "Fine procedura ...." << std::endl;
return 0;
}
Now besides guessing that the pointer to Class1 may not be contained in the _T pointer, I don't understand why this code works without problems on all conditions (in case the class is derived and the function is virtual, in the case of multiple inheritance, in the case that the function is present only in the base class, etc ...). At the end I'm not telling the compiler to call an address of a class (Class1), that the compiler knows well, and that this function is at some offset from the class pointer and that the signature of that function is similar to the one stored later after the cast.
I have not used C++ in a long time. I'm trying to display some polymorphic behavior:
class func {
public:
virtual void print() = 0;
};
class func1 : public func {
public:
void print () { cout << "FUNC 1" << endl; };
};
class func2 : public func {
public:
void print () { cout << "FUNC 2" << endl; };
};
static map<string,func *> myMap;
static func1 f1 = func1 ();
static func2 f2 = func2 ();
myMap["func1"] = &f1;
myMap["func2"] = &f2;
So In my main function, when I call:
myMap["func1"]->print();
myMap["func2"]->print();
I would expect:
FUNC 1
FUNC 2
Not sure if this is the right way to do this. When I compile the code, it gives me this error:
test.cc:31: error: expected constructor, destructor, or type conversion before ‘=’ token
test.cc:32: error: expected constructor, destructor, or type conversion before ‘=’ token
Which refers to these lines:
myMap["func1"] = &f1;
myMap["func2"] = &f2;
Thank you.
Expression statements, like those assignment statements, can only go inside functions.
In C++11, you can initialise the static map using brace-initialisation:
static map<string,func *> myMap = {
{"func1", &f1},
{"func2", &f2}
};
If you're stuck in the past, then either populate it in a function (perhaps main, or something you call before doing anything with the map), or write a function to return a populated map:
std::map<string,func*> make_map() {
std::map<string,func*> map;
map["func1"] = &f1;
map["func2"] = &f2;
return map;
}
static std::map<string,func *> myMap = make_map();
A better idea might be to avoid non-trivial global variables, if possible; they often bring a world of pain.
Consider following programme
#include <iostream>
#include <typeinfo>
template <class T>
void Output(const char * Str, T Func)
{
void *Ptr = reinterpret_cast<void *>(Func);
std::ptrdiff_t Num = reinterpret_cast<std::ptrdiff_t>(Ptr);
std::cout << Str << " " << Num << std::endl;
}
class TAnotherBase { long a[10]; };
struct TBase {
typedef void (TBase::*TFunc)();
TFunc Func;
TBase(TFunc F) {
Func = F;
Output("Ctor TBase ", Func);
}
void CallF() {
std::cout << "This in TBase: " << typeid(this).name() << " " << this << std::endl;
(this->*Func)();
}
};
struct TDerived: public TAnotherBase, public TBase {
TDerived(): TBase(static_cast<TBase::TFunc>(&TDerived::F)) {
Output("Ctor TDerived ", &TDerived::F);
CallF();
}
void F() {
std::cout << "This in TDerived::F: " <<typeid(this).name() << " " << this << std::endl;
}
};
int main(int argc, char **argv) {
TDerived Derived;
return 0;
}
It generates this output:
Ctor TBase 4197502 (1)
Ctor TDerived 4197502 (2)
This in base: P5TBase 0x7fff6b30fc00 (3)
This in TDerived::F: P8TDerived 0x7fff6b30fbb0 (4)
What is going on here
I have function F in TDerived class, then I send pointer to the function to TBase class: TDerived(): TBase(static_cast<TBase::TFunc>(&TDerived::F)) { and (1) output function pointer.
Then I output function pointer in TDerived class (2) and make TBase class to call the function: `CallF(); (4), (5).
TAnotherBase is here to make different this pointers of TBase and TDerived classes.
So, first question.
I read that function pointers is more like offsets relative to this. If so, why I get the same function pointer values in (1) and (2) - 4197502 ?
Second question
I output this in CallF function (3) and it is all right. But then I call function (this->*Func)(); via this (which is TBase) and in function F this magically becomes completely different this (4)! It changes its type and value! How it is possible? How compiler still remembers that Func (which type is typedef void (TBase::*TFunc)();) is actually from TDerived class? How compiler knows that it should adjust this before sending it to F? Why and how it works?
An example of one way this can be done is described in the Itanium ABI - if you're interested in how the C++ class model can be implemented I highly recommend reading that whole document.
When you convert from a pointer-to-derived-member-function to pointer-to-base-member-function the compiler knows that when you call it this will point to base not derived. So it needs to make sure that the first thing it does is to modify this back from base* to derived*. It can either do this by inventing a shim function which modifies this and jumps to the real function, or by just storing the offset along with the pointer and using it at the call site (which is what the reference above describes). Or I'm sure there are other ways.
(static_cast is not just a compile time operation; quite often it has to do real work at runtime.)
I need to declare a good number of simple POD structures that will behave the same but that are really different types, i.e not typedefs.
Anyway I just want to keep them as simple as possible. But while testing I saw that the compiler performs some implicit conversions and I'd like to avoid this.
Given this code :
template<typename T>
struct Struct {
T data;
operator T() const { return data; }
};
void fun(Struct<float> value)
{
cout << "Call with Struct :: " << value << endl;
}
void fun(int value)
{
cout << "Call with INT :: " << value << endl;
}
int main(int, char**)
{
fun(3);
fun(4.1f);
fun(Struct<float>{5.2});
fun(Struct<double>{6.3});
return 0;
}
Compiled with GCC.
The execution gives me :
Call with INT :: 3 // Ok
Call with INT :: 4 // [1]
Call with Struct :: 5.2 // Ok
Call with INT :: 6 // [2]
How can I avoid implicit conversions [1] and [2] ?
Thanks
As requested in the comment :
The use of the explicit keyword for operator T() will actually prevent implicit type conversion.
Thus, declaring the struct this way:
template<typename T>
struct Struct {
T data;
explicit operator T() const { return data; }
};
will make the compiler prevent implicit conversion, and require that the client code specifically ask for a conversion (i.e. use T(Struct<T>) anywhere a T is required )
Why is the following code results in error :
class A {
public:
typedef void (A::*funptr)(void);
void fun(void ) {
cout << " Fun Call " <<endl;
}
void foo(void ) {
cout << " Foo Call " <<endl;
}
funptr p[2];
funptr q;
A()
{
p[0]=&A::foo;
p[1]=&A::fun;
q =&A::fun;
}
};
int main ()
{
A obj;
(obj.*q)(void);
//(obj.p[0])();
//(obj.p[1])();
return 0;
}
You will need to call it like this:
(obj.*obj.q)();
The .* operator doesn't take a member name on the right-hand side, but rather an expression that evaluates to a member pointer. When you write this:
(obj.*q)();
It is looking for a variable called q, but there is no such variable in scope.
Change all occurrences of (void) to (). On the declarations it's redundant, and on the call itself it's not allowed.