Dynamic Casting

Dynamic casting, means that you can convert one object into another that is off the same type. For example, if you had a base class called Shape and a inherited class called Rectangle then you are able to convert a Shape object into a Rectangle.

Rectangle *rec = dynamic_cast<Shape *>(shapeobject);

sort of thing, there has to be a virtual function within the base class otherwise the compiler will complain, but apart from that that is about it.

Dynamic casting allows for NULL returns which is the best thing, because you can test to see if the casting actually worked and not to do anything silly on a NULL object which would crash the program.

Pointer casting uses the sytnax

<type> *p_subclass = dynamic_cast<<type> *>( p_obj );

Reference will not throw an error/expcetion so will need to check std::bad_cast< typeinfo header >, here is the syntax

<type> subclass = dynamic_cast<<type> &>( ref_obj );

Hopefully this will make more sense for how and why it works.

#include <iostream>
 
using namespace std;
 
class classA 
{
	public	:
		int x;		// should be private
		char y;		// should be private
 
		classA();
 
 		virtual ~classA() {}; 	// need to have a virtual function for dynamic casting
};
 
// basic classA constructor
classA::classA()
{ 
	cout << "classA" << endl; 
	x = 1; 
	y = 'a';
}
 
 
class classB : public classA
{	
	public :
		int b;		// should be private
 
		classB();
 
		~classB() {};	// complete the virtual
};
 
// basic classB constructor
classB::classB()
{
	cout << "classB" << endl;
	x = 2;
	y = 'b';
}
 
int main()
{
	classA newa;	// classA obj
	cout << "class A constructed" << endl;
	classB newb;	// classB obj
	cout << "class B constructed" << endl;
 
	cout << "NewA X " << newa.x << endl;
	cout << "NewB X " << newb.x << endl;
 
	// point a classB to a already created classB object
	classB *normalB = &newb;
	// dynamic_cast a normalB object (newb) to another classA object
	classA *dynA = dynamic_cast<classB *>(normalB);	
	cout << "dynamic A X " << dynA->x << endl;
 
	// does not work, because you cannot convert classA into a classB, but if classA was pointing to a classB type.
	classA *normalA = &newa;
	classB *dynB = dynamic_cast<classB *>(normalA);
	if (dynB)	// above produces a 0 because invalid.
	{
		cout << "dynamic B X " << dynB->x << endl;
		cout << "dynamic B X " << dynB->b << endl;
	}
 
	// this does work because it is converting from a pointer of classB type, which was "sitting" in a classA container
	// and then is converted back to a classB
	classA *normalA2 = &newb;
	classB *dynB2 = dynamic_cast<classB *>(normalA2);
	if (dynB2)	// above produces a 0 because invalid.
	{
		cout << "dynamic A2X " << normalA2->x << endl;	// output is 2 because it was a classB constructed
		cout << "dynamic B X " << dynB2->x << endl;
		cout << "dynamic B X " << dynB2->b << endl;
	}
 
}

Leave a Reply

Your email address will not be published.