Вот вам еще вариант:
pastebin.com/RZAY789w
умеет:
typedef std::unique_ptr< IObject > ptr;
ptr p = CreateObject< Object3 >();
assert( FastObjectCast< Object3 >( p.get() ) );
assert( FastObjectCast< Object1 >( p.get() ) ); // Object3 inherits Object1
assert( !FastObjectCast< INamedObject >( p.get() ) ); // p is unnamed Object3
ptr q = CreateObject< Object3 >( "some name" );
assert( FastObjectCast< Object3 >( q.get() ) );
assert( FastObjectCast< Object1 >( q.get() ) ); // Object3 inherits Object1
assert( FastObjectCast< INamedObject >( q.get() ) ); // p is named Object3
INamedObject наследуется также реализует IObject
FastObjectCast семантически эквивалентен dynamic_cast, но раз в 10 быстрее (dynamic_cast тоже можно использовать).
p.s.
Так нельзя делать:
template<class T> T * As() { return (T*)this; }
Нужно использовать static_cast, т.к. после каста указатель может поменять значение на пару байт (это происходит из-за множественного наследования, если оно есть в иерархии).