#include <cstdio>
using namespace std;
class A {
public:
virtual void func() { printf("A::func()"); }
};
class B : public A {
public:
virtual void func() { printf("B::func()"); }
};
int main() {
A a = *(A *)new B();
a.func();
}
The question is simple: why a->func() calls function in class A even though a contains object of class B?
Here’s what happens in this code, step by step:
new B(): a new object of type B is allocated on the free store, resulting in its address(A*): the address of the object is cast toA*, so we have a pointer of typeA*actually pointing to an object of type B, which is valid. All OK.A a: here the problems start. A new local object of type A is created on the stack and constructed using the copy constructorA::A(const A&), with the first paremeter being the object created before.new.a.func()– the method is called on the (local) object of class A.If you change the code to:
then only one object will be constructed, its pointer will be converted to pointer of type
A*, then dereferenced and a new reference will be initialized with this address. The call of the virtual function will then be dynamically resolved toB::func().But remember, that you’d still need to free the object since it was allocated with
new:Which, by the way, will only be correct if A has a virtual destructor, which is required that B::~B() (which luckily is empty here, but it doesn’t need to in the general case) will also be called. If A doesn’t have a virtual destructor, then you’d need to free it by:
If you would want to use a pointer, then that’s the same as with the reference. Code: