A a = *(A *)new B();
a.func();
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 to A*
, so we have a pointer of type A*
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 constructor A::A(const A&)
, with the first paremeter being the object created before.
- The pointer to the original object of type B is lost after this statement, resulting in a memory leak, since it was allocated on the free store with
new
.
a.func()
- the method is called on the (local) object of class A.
If you change the code to:
A& a = *( A*) new B();
a.func();
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 to B::func()
.
But remember, that you'd still need to free the object since it was allocated with new
:
delete &a;
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:
delete (B*)&a;
If you would want to use a pointer, then that's the same as with the reference. Code:
A* a = new B(); // actually you don't need an explicit cast here.
a->func();
delete (B*)a; // or just delete a; if A has a virtual destructor.