Fun with dynamic casting

January 29th, 2010 by ofer
Posted in Coding

Polymorphism allows for different function implementations to be called, depending on values only known at run time. For instance:

class BaseA {
	public:
		virtual void foo(){cout<<"Base";};
};

class A: public BaseA {
	public:
		void foo(){cout<<"Child";};
};

A a;
BaseA & base = a;
base.foo();

Will print “Child”.

“Pair polymorphism” is when you want a specific function implementation to be called based on the run time value of two different instances of a class. For instance in the case of:

class BaseA {
};

class BaseB {
	public:
		virtual void foo (BaseA & a) = 0;
};

class A: public BaseA {
};

class B: public BaseB {
	public:
		void foo (A & a);
};

You would want that somehow “void B::foo (A & a)” will be called. The code I posted does not do this.
There is a way to do this, but it requires for a class to know about the implementation classes. It is not a problem in some cases. However, sometimes you want to have an abstraction layer.
An abstraction layer is a set of classes or interfaces, that have no methods or “don’t know” anything about the classes that implement them. For instance you can have a graphics abstraction layer.
You could implement this layer with DirectX. However, this layer will make it easier to afterwards add an implementation with OpenGL without having to make a lot of changes, even if the game is already completed.

How are we going to have a “pair polymorphism” in this case? One solution is using dynamic casting. You can cast a pointer of a parent class to it’s child class(in case the run time value really points to an instance of that class).
Some code:

class BaseA {
};

class BaseB {
	public:
		virtual void foo (BaseA & a) = 0;
};

class A: public BaseA {
};

class B: public BaseB {
	public:
		void foo (BaseA & a)
		{
			foo2 (dynamic_cast<A &>(a));
		}
		void foo2 (A & a);
};

I was asked by someone how this can be done without dynamic casting, because he doesn’t like dynamic casting. I found a way, but it ain’t pretty, and I honestly can’t find any advantage of using this code instead of just using dynamic casting. But here it is:

class BaseA {
	public:
		virtual void DynamicCast() = 0;
};

class BaseB {
	public:
		virtual void foo (BaseA & base) = 0;
};

class A;

class Caster {
	public:
		A * a;
};

class A: public BaseA {
	public:
		Caster * c;
		void DynamicCast()
		{
			c->a = this;
		}
};

class B: public BaseB {
	public:
		Caster * c;
		void foo (BaseA & base)
		{
			base.DynamicCast();
			foo2 (c->a);
		}
		void foo2 (A & a);
};
Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks

Leave a Reply