Casting
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; }