Home C++ Introduction Decisions Loops Input/Output Functions Stack and Heap References Arrays Searching and Sorting Recursion Pointers Character and Strings Structures Classes Inheritance Exceptions Templatess Casting STL Modern C++ Misc Books ----

Casting


Contents

Dynamic Cast

Dynamic casting is used when we have inheritance. We can always upcase safely because a derived class is a base class also. However we can only downcast to a class when the original object is of that type.
File: dynamic1.cpp
#include <iostream>
using namespace std ;

class A
{
    public:
     int x1 ;
     virtual void function1()
      {
      }
};

class B : public A
{
    public:
     int x1B ;
};

class C : public A
{
    public:
     int x1C ;

};

class D
{
};

class Person
{
   public:
     virtual void function1()
      {
      }

};

class Employee : public Person
{
};


class Student : public  Person
{
};



int main()
{
    A* aObject = new B() ;
    //Should not be allowed.
    D* dObject = (D*)aObject ;

    dObject = dynamic_cast<D*> (aObject) ;
    if ( dObject == NULL )
      cout << "Invalid cast from A to D." << endl ;
    else
      cout << "Valid cast from A to D." << endl ;

    //Should not be allowed.
    C* cObject = (C*)aObject ;

    cObject = dynamic_cast<C*> (aObject) ;
    if ( cObject == NULL )
      cout << "Invalid cast from A to C." << endl ;
    else
      cout << "Valid cast from A to C." << endl ;


    B* bObject = (B*)aObject ;
    bObject = dynamic_cast<B*> (aObject) ;
    if ( bObject == NULL )
      cout << "Invalid cast from A to B." << endl ;
    else
      cout << "Valid cast from A to B." << endl ;


   Person* personObject = new Employee() ;
   Student* studentObject = (Student*)personObject ;

    studentObject = dynamic_cast<Student*> (personObject) ;
    if ( studentObject == NULL )
      cout << "Invalid cast from Person to Student." << endl ;
    else
      cout << "Valid cast from Person to Student." << endl ;



}
$ g++ dynamic1.cpp ; ./a.exe
Invalid cast from A to D.
Invalid cast from A to C.
Valid cast from A to B.
Invalid cast from Person to Student.

The "C" style casting does not perform any checking
as far as the class types go. We are able to cast from
"A" to "D" even though "D" is not derived from "A" and
is not the original object. However "dynamic_cast"
catches these errors. We should use "dynamic_cast" whenever
we are downcasting classes.

File: dynamic2.cpp
#include <iostream>
using namespace std ;

class A
{
    public:
     int x1 ;
     virtual void function1()
      {
      }
};

class B : public A
{
    public:
     int x1B ;
};

class C : public A
{
    public:
     int x1C ;

};


int main()
{

     B bObject ;
     bObject.x1B = 22 ;
     A* aObject = &bObject  ;
     //Not valid as aObject contains bObject as the
     //underlying object
     C* cObject = dynamic_cast<C*> (aObject) ;
     printf( "Pointer value: %p\n" , cObject ) ;
     if ( cObject != NULL )
       cout << cObject->x1C   << endl ;

     A& refAObject = bObject ;
     try
     {
       C& refCObject = dynamic_cast<C&> ( refAObject ) ;
     }
     catch (const bad_cast& e)
     {
             cerr << "Exception: " << e.what() << endl;
     }

}

$ g++ dynamic2.cpp ; ./a.exe
rm: cannot remove 'a.exe': No such file or directory
Pointer value: 0x0
Exception: std::bad_cast

The base class contains a virtual function:

	 virtual void function1()
	  {
	  }

This is necessary in order to use dynamic casting.
Dynamic casting needs RTTI( Run-Time Type Information)
which is implemented if there is a virtual function somewhere
in the base class. Otherwise we will get a compiler error
of the form:

dynamic1.cpp: In function ‘int main()’:
dynamic1.cpp:36:19: error: cannot ‘dynamic_cast’ ‘aObject’ (of type ‘class A*’) to type ‘class C*’ (source type is not polymorphic)
   36 |      C* cObject = dynamic_cast (aObject) ;




   C* cObject = dynamic_cast (aObject) ;
     printf( "Pointer value: %p\n" , cObject ) ;
     if ( cObject != NULL )
       cout << cObject->x1C   << endl ;

In the above snippet; we know that the base class pointer
"aObject" contains the B class pointer.

A* aObject = &bObject  ;

So the type casting to "C^" should fail. With pointer casting
the value of "cObject" is null as shown in the output. With
references the behavior is slightly different. We have an exception
that is thrown.


 A& refAObject = bObject ;
     try
     {
       C& refCObject = dynamic_cast ( refAObject ) ;
     }
     catch (const bad_cast& e)
     {
	         cerr << "Exception: " << e.what() << endl;
     }