fork download
  1. #include <stdio.h>
  2.  
  3. #define TRAIT_DEF( trait_name ) \
  4. class Trait_##trait_name \
  5. { \
  6. public: \
  7. virtual void trait_name( void ) = 0; \
  8. }
  9. #define TRAIT_USE( trait_name, class_name ) \
  10. Trait_##trait_name##_##class_name m_Trait_##trait_name; \
  11. public: \
  12. Trait_##trait_name* GetTrait_##trait_name( void ){ return &m_Trait_##trait_name; } \
  13. friend class Trait_##trait_name##_##class_name
  14. #define TRAIT_INIT( trait_name ) m_Trait_##trait_name(this)
  15. #define TRAIT_HELPER_DEF( trait_name, class_name ) \
  16. class Trait_##trait_name##_##class_name : public Trait_##trait_name \
  17. { \
  18. class class_name* m_pTarget; \
  19. public: \
  20. Trait_##trait_name##_##class_name( class_name* p ) : m_pTarget( p ){} \
  21. virtual void trait_name( void ); \
  22. }
  23. #define TRAIT_HELPER_DEF_AFTER( trait_name, class_name ) \
  24. void Trait_##trait_name##_##class_name::trait_name( void ) \
  25. { \
  26. m_pTarget->trait_name(); \
  27. }
  28.  
  29. TRAIT_DEF( Draw );
  30. TRAIT_DEF( Update );
  31. TRAIT_DEF( Jump );
  32.  
  33. TRAIT_HELPER_DEF( Draw, A );
  34. TRAIT_HELPER_DEF( Update, A );
  35. class A
  36. {
  37. TRAIT_USE( Draw, A );
  38. TRAIT_USE( Update, A );
  39. public:
  40. A() : TRAIT_INIT( Draw ), TRAIT_INIT( Update ){}
  41. void Draw( void ){ printf( "A::Draw\n" ); }
  42. void Update( void ){ printf( "A::Update\n" ); }
  43. };
  44. TRAIT_HELPER_DEF_AFTER( Draw, A );
  45. TRAIT_HELPER_DEF_AFTER( Update, A );
  46.  
  47. TRAIT_HELPER_DEF( Draw, B );
  48. TRAIT_HELPER_DEF( Jump, B );
  49. class B
  50. {
  51. TRAIT_USE( Draw, B );
  52. TRAIT_USE( Jump, B );
  53. public:
  54. B() : TRAIT_INIT( Draw ), TRAIT_INIT( Jump ){}
  55. void Draw( void ){ printf( "B::Draw\n" ); }
  56. void Jump( void ){ printf( "B::Jump\n" ); }
  57. };
  58. TRAIT_HELPER_DEF_AFTER( Draw, B );
  59. TRAIT_HELPER_DEF_AFTER( Jump, B );
  60.  
  61. int main( void )
  62. {
  63. A a;
  64. B b;
  65. Trait_Draw* pDrawA = a.GetTrait_Draw();
  66. Trait_Draw* pDrawB = b.GetTrait_Draw();
  67. pDrawA->Draw();
  68. pDrawB->Draw();
  69. Trait_Update* pUpdate = a.GetTrait_Update();
  70. pUpdate->Update();
  71. Trait_Jump* pJump = b.GetTrait_Jump();
  72. pJump->Jump();
  73. return 0;
  74. }
Success #stdin #stdout 0s 2684KB
stdin
Standard input is empty
stdout
A::Draw
B::Draw
A::Update
B::Jump