Index

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
}
Index