fork(1) download
  1. class DynamicCastable {
  2. public:
  3. virtual const std::string& GetClassId (void) const = 0;
  4. virtual void* BottomInstance (void) = 0;
  5. virtual const void* BottomInstance (void) const = 0;
  6. virtual void* CastTo (const std::string& classId) = 0;
  7. virtual const void* CastTo (const std::string& classId) const = 0;
  8. // requires static const std::string A::ClassId (void);
  9. template <typename T> T* Cast (void)
  10. { return static_cast<T*>(CastTo(T::ClassId()); }
  11. template <typename T> const T* Cast (void) const
  12. { return static_cast<T*>(CastTo(T::ClassId()); }
  13. }
  14.  
  15.  
  16. class A : public DynamicCastable {
  17. ...implement interface here..
  18. const std::string WhoAmI (void) { return "A"; }
  19. };
  20.  
  21. class B : public A {
  22. ...refine interface here..
  23. const std::string WhoAmI (void) { return "B"; }
  24. };
  25.  
  26. class C : public B {
  27. ...refine interface here..
  28. const std::string WhoAmI (void) { return "C"; }
  29. };
  30.  
  31. void Test (void) {
  32. A* a = new C();
  33. assert(a->Cast<C>().WhoAmI() == "C"); // should pass
  34. assert(a->Cast<B>().WhoAmI() == "B"); // should pass
  35. assert(a->Cast<A>().WhoAmI() == "A"); // should pass
  36. B* b = a->Cast<B>();
  37. C* c = a->Cast<C>();
  38. // in most compilers will print 1 thrice
  39. printf("&A==&B is %u\n", (unsigned) ((void*) a) == ((void*) b));
  40. printf("&B==&C is %u\n", (unsigned) ((void*) b) == ((void*) c));
  41. printf("&C==&A is %u\n", (unsigned) ((void*) c) == ((void*) a));
  42. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
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'
stdout
Standard output is empty