class DynamicCastable { public: virtual const std::string& GetClassId (void) const = 0; virtual void* BottomInstance (void) = 0; virtual const void* BottomInstance (void) const = 0; virtual void* CastTo (const std::string& classId) = 0; virtual const void* CastTo (const std::string& classId) const = 0; // requires static const std::string A::ClassId (void); template <typename T> T* Cast (void) { return static_cast<T*>(CastTo(T::ClassId()); } template <typename T> const T* Cast (void) const { return static_cast<T*>(CastTo(T::ClassId()); } } class A : public DynamicCastable { ...implement interface here.. const std::string WhoAmI (void) { return "A"; } }; class B : public A { ...refine interface here.. const std::string WhoAmI (void) { return "B"; } }; class C : public B { ...refine interface here.. const std::string WhoAmI (void) { return "C"; } }; void Test (void) { A* a = new C(); assert(a->Cast<C>().WhoAmI() == "C"); // should pass assert(a->Cast<B>().WhoAmI() == "B"); // should pass assert(a->Cast<A>().WhoAmI() == "A"); // should pass B* b = a->Cast<B>(); C* c = a->Cast<C>(); // in most compilers will print 1 thrice printf("&A==&B is %u\n", (unsigned) ((void*) a) == ((void*) b)); printf("&B==&C is %u\n", (unsigned) ((void*) b) == ((void*) c)); printf("&C==&A is %u\n", (unsigned) ((void*) c) == ((void*) a)); }
Standard input is empty
prog.cpp:3:21: error: 'string' in namespace 'std' does not name a type
virtual const std::string& GetClassId (void) const = 0;
^
prog.cpp:6:35: error: 'string' in namespace 'std' does not name a type
virtual void* CastTo (const std::string& classId) = 0;
^
prog.cpp:7:41: error: 'string' in namespace 'std' does not name a type
virtual const void* CastTo (const std::string& classId) const = 0;
^
prog.cpp:13:1: error: expected ';' after class definition
}
^
prog.cpp: In member function 'T* DynamicCastable::Cast()':
prog.cpp:10:48: error: expected ')' before ';' token
{ return static_cast<T*>(CastTo(T::ClassId()); }
^
prog.cpp: In member function 'const T* DynamicCastable::Cast() const':
prog.cpp:12:48: error: expected ')' before ';' token
{ return static_cast<T*>(CastTo(T::ClassId()); }
^
prog.cpp: At global scope:
prog.cpp:17:1: error: expected unqualified-id before '...' token
...implement interface here..
^
prog.cpp:22:1: error: expected unqualified-id before '...' token
...refine interface here..
^
prog.cpp:27:1: error: expected unqualified-id before '...' token
...refine interface here..
^
prog.cpp: In function 'void Test()':
prog.cpp:32:15: error: invalid new-expression of abstract class type 'C'
A* a = new C();
^
prog.cpp:26:7: note: because the following virtual functions are pure within 'C':
class C : public B {
^
prog.cpp:4:16: note: virtual void* DynamicCastable::BottomInstance()
virtual void* BottomInstance (void) = 0;
^
prog.cpp:5:22: note: virtual const void* DynamicCastable::BottomInstance() const
virtual const void* BottomInstance (void) const = 0;
^
prog.cpp:6:16: note: virtual void* DynamicCastable::CastTo(const int&)
virtual void* CastTo (const std::string& classId) = 0;
^
prog.cpp:7:22: note: virtual const void* DynamicCastable::CastTo(const int&) const
virtual const void* CastTo (const std::string& classId) const = 0;
^
prog.cpp:33:22: error: request for member 'WhoAmI' in 'a->A::<anonymous>.DynamicCastable::Cast<C>()', which is of pointer type 'C*' (maybe you meant to use '->' ?)
assert(a->Cast<C>().WhoAmI() == "C"); // should pass
^
prog.cpp:33:37: error: 'assert' was not declared in this scope
assert(a->Cast<C>().WhoAmI() == "C"); // should pass
^
prog.cpp:34:22: error: request for member 'WhoAmI' in 'a->A::<anonymous>.DynamicCastable::Cast<B>()', which is of pointer type 'B*' (maybe you meant to use '->' ?)
assert(a->Cast<B>().WhoAmI() == "B"); // should pass
^
prog.cpp:35:22: error: request for member 'WhoAmI' in 'a->A::<anonymous>.DynamicCastable::Cast<A>()', which is of pointer type 'A*' (maybe you meant to use '->' ?)
assert(a->Cast<A>().WhoAmI() == "A"); // should pass
^
prog.cpp:39:63: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
printf("&A==&B is %u\n", (unsigned) ((void*) a) == ((void*) b));
^
prog.cpp:39:64: error: 'printf' was not declared in this scope
printf("&A==&B is %u\n", (unsigned) ((void*) a) == ((void*) b));
^
prog.cpp:40:63: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
printf("&B==&C is %u\n", (unsigned) ((void*) b) == ((void*) c));
^
prog.cpp:41:63: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
printf("&C==&A is %u\n", (unsigned) ((void*) c) == ((void*) a));
^
prog.cpp: In instantiation of 'T* DynamicCastable::Cast() [with T = C]':
prog.cpp:33:20: required from here
prog.cpp:10:46: error: 'ClassId' is not a member of 'C'
{ return static_cast<T*>(CastTo(T::ClassId()); }
^
prog.cpp: In instantiation of 'T* DynamicCastable::Cast() [with T = B]':
prog.cpp:34:20: required from here
prog.cpp:10:46: error: 'ClassId' is not a member of 'B'
prog.cpp: In instantiation of 'T* DynamicCastable::Cast() [with T = A]':
prog.cpp:35:20: required from here
prog.cpp:10:46: error: 'ClassId' is not a member of 'A'
Standard output is empty