I want to call the child's function from parent's function in reinterpreted class, like below.
Example
#include <iostream>
class A {
public:
void func1() {
// some code
func2();
// some code
}
protected:
virtual void func2() {
printf("class A\n");
}
};
class B : public A {
protected:
virtual void func2() {
printf("class B\n");
}
};
int main() {
A* ab = new A();
ab->func1(); // this print "class A"
B* bab = reinterpret_cast<B*>(ab);
bab->func1(); // this also print "class A"
// I want to print "class B" when I use bab->func1()
}
In this situation, Is there any way to print class B using the reinterpreted class bab
without redefining func1
?
CodePudding user response:
For C polymorphism to kick in, you must create an instance of the derived class somewhere, but you can store a pointer to the base class. Using the base-class pointer will dispatch to the overridden functions of the derived class. So your definition of A
and B
is fine, your usage in the main function is not. reinterpret_cast
is not intended for this.
#include <iostream>
#include <memory>
class A {
public:
void func1() {
// some code
func2();
// some code
}
protected:
virtual void func2() {
printf("class A\n");
}
};
class B : public A {
protected:
virtual void func2() {
printf("class B\n");
}
};
int main() {
{
// This works, but don't do this. Naked "new" is not modern C and dangerous.
A* ab = new B();
ab->func1();
delete ab;
}
{
// VARIANT 2: use smart pointers
std::unique_ptr<A> ab = std::make_unique<B>();
ab->func1();
}
{
// VARIANT 3: A non-smart pointer is okay, as long as it
// 1. references an existing allocated object
// 2. the pointer does not outlive the object it points to
B b;
A* ab = &b;
ab->func1();
}
{
// VARIANT 4: Like Variant 3, but with reference instead of pointer
B b;
A& ab = b;
ab.func1();
}
}
Output
class B
class B
class B
class B
https://godbolt.org/z/8e5E85nx5
EDIT: Try to avoid allocation with new
. Any memory allocated in this fashion must be freed by you using delete
and it is very easy to forget (I did when I first wrote this answer, kinda proving my point). Even if you do delete the memory at the end of your function, there is the possibility that your code never reaches this statement, e.g. if exceptions are thrown somewhere between new
and delete
.Here is some further reading: