C & C++ Programming - RTTI & Casting
///////////////////////////////////////////////////////////////////////////////////////////////
// Polymorphic Class are the classes that use virtual function
//-------------------------------------------------------------
// Whenever using dynamic_cast Enable Run-Time Type Information.
//
// To find this option in the development environment,
// click Settings on the Project menu. Then click the C/C++ tab,
// and click C++ Language in the Category box.
//-------------------------------------------------------------
// Run-time type information (RTTI) is a mechanism that allows the type of an object
// to be determined during program execution. RTTI was added to the C++ language
because
// many vendors of class libraries were implementing this functionality themselves.
// This caused incompatibilities between libraries. Thus, it became obvious that
support
// for run-time type information was needed at the language level.
//
// For the sake of clarity, this discussion of RTTI is almost completely restricted
to pointers
// However, the concepts discussed also apply to references.
//
// There are three main C++ language elements to run-time type information:
//
// *The dynamic_cast operator.
// Used for conversion of polymorphic types. See dynamic_cast Operator for more
information.
//
// *The typeid operator.
// Used for identifying the exact type of an object.
//
// *The type_info class.
// Used to hold the type information returned by the typeid operator.
///////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
class A
{
public:
A()
{
cout << "CTOR A\n";
}
~A()
{
cout << "DTOR A\n";
}
private:
virtual void funcA(){}
};
class B
{
public:
B()
{
cout << "CTOR B\n";
}
~B()
{
cout << "DTOR B\n";
}
virtual void funcB()
{
cout << "Virtual Function B\n";
}
};
class C : public B
{
public:
C()
{
cout << "CTOR C\n";
}
~C()
{
cout << "DTOR C\n";
}
void funcB()
{
cout << "Virtual Function C\n"; }
};
class D : public C
{
public:
D()
{
cout << "CTOR D\n";
}
~D()
{
cout << "DTOR D\n";
}
void funcB()
{
cout << "Virtual Function D\n";
}
};
void Upcast(B* f_pb)
{
cout << "1.\n";
C* pc = dynamic_cast < C* >(f_pb); // ok: C is a direct base class
// pc points to C subobject of pd
pc->funcB();
cout << "2.\n";
B* pb = dynamic_cast < B* >(f_pb); // ok: B is an indirect base class
// pb points to B subobject of pd
pb->funcB();
}
void Downcast()
{
B* pb = new D; // unclear but ok
B* pb2 = new B;
cout << "3\n";
D* pd = dynamic_cast< D* >(pb); // ok: pb actually points to a D
pd->funcB();
cout << "4\n";
D* pd2 = dynamic_cast< D* >(pb2); // error: pb2 points to a B, not a D
// pd2 == NULL
// Will not work
// pd2->funcB();
}
void Voidcast()
{
cout << "5\n";
A* pa = new A;
cout << "6\n";
B* pb = new B;
void* pv = dynamic_cast< void* >(pa); // pv now points to an object of type
A
pv = dynamic_cast< void* >(pb); // pv now points to an object of type B
}
void TestRTTI()
{
// Not Working - downcasting not allowed
//B *pb = new B;
//C *pb = new B;
//D *pb = new B;
// Working - upcast
B *pb = new C;
// Virtual function of class C is called
// Working - upcast
C *pc = new C;
// Virtual function of class C is called
// Working - upcast
B *pb1 = new D;
// Virtual function of class D is called
// Working - upcast
C *pc1 = new D;
// Virtual function of class D is called
// Working - upcast
D *pd = new D;
// Virtual function of class D is called
Upcast(pd);
///////////////////////////////////////////
// Downcasting
Downcast();
///////////////////////////////////////////
// Voidcast
Voidcast();
cout << "****************************\n";
cout << "deleting object pointer\n";
delete pb; // DTOR B
delete pc; // DTOR C DTOR B
delete pb1; // DTOR B
delete pc1; // DTOR C DTOR B
delete pd; // DTOR D DTOR C DTOR B
}