im adding a short code. can you please explain me why the following dynamic casting execute what i wrote? i dont understand when this casting fails or not..
#ifndef MOED_B
#define MOED_B
#include <iostream>
using namespace std;
class Base
{
public:
Base() {cout<<"Base: default constructor"<<endl;}
virtual void f() {cout<<"Base:f"<<endl;}
void i() {cout<<"Base: fun I"<<endl;}
};
class B: public Base
{
public:
virtual ~B() {cout<<"B: destructor "<<endl;}
void f() {cout<<"B: fun F"<<endl;}
virtual void h()=0;
virtual void i() {cout<<"B: fun I"<<endl;}
int j() {cout<<"B: fun J"<<endl;return 2;}
};
class C:public Base
{
public:
int iN;
C *c;
C() {iN=1;}
~C() {cout<<"C: fun F"<<endl;}
void f() {cout<<"C: fun F"<<endl;}
void h() {cout<<"C: fun I"<<endl;}
virtual void i() {cout<<"C: fun I"<<endl;}
int j() {cout<<"C: fun J"<<endl;return c->iN;}
};
class D: public C{
public:
int iN;
C *c;
D() {iN=2;}
~D() {cout<<"D: destructor "<<endl;}
void h() {cout<<"D: fun H"<<endl;}
int j() {cout<<"D: fun J"<<endl;return c->iN;}
};
class E:public B{
public:
int iN;
C *c;
E() {iN=3;}
~E() {cout<<"E:destructor "<<endl;}
void h() {cout<<"E: fun H"<<endl;}
int j() {cout<<"E: fun J"<<endl;return c->iN;}
void f() {cout<<"E: fun F"<<endl;}
};
#endif
---------the main section:----------
D* d0=dynamic_cast<D*>(&c); // why not??
D* d1=dynamic_cast<D*>(b); //why not??
C* d2=dynamic_cast<D*>(base2); //why works???
C* d3=dynamic_cast<C*>(base2); //why works??
18: c is of type C, and holds only an object of type C, so you can't cast it to a D. What you are doing in line 14 is called "object slicing"; you are throwing away the parts of d that are not in C to create c.
19: b points to an object of type E, which has no relation to D. What did you expect to get here?
20: base2 is pointing to a D, so you can convert to a D with no issues.
21: base2 is pointing to a D, which is inheriting from C, so you put that in a pointer to a C with no issues.
No, you used the address-of operator so you did have a pointer. The pointer was simply pointing to a C, which cannot be cast to point to a D object since a D object has members and methods that a C doesn't have.
In terms of just accessing the member c, there is no difference. That kind of access (line 13) could be important if you have multiple members defined in different base classes with the same name so you can access each of them.
The desctructor is called when you delete something; that is the point of delete. What are you seeing that makes you think this doesn't happen? I'd also note that you have a memory leak on line 12 and 13, since both objects allocated there are never deleted.