Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

More C++ Idioms/Hierarchy Generation

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

Hierarchy Generation Intent To generate a concrete class composed to various behavioral policies Also Known As Motivation When a solution calls for a number of different implementations that can be combine in a variety of ways, each sharing or not sharing various decorations, the traditional solution is multiple inheritance which produces a variety of problems. Hierarchy generation is a pattern by which a variety of base classes are successively inherited to avoid multiple inheritance. Solution and Sample Code #include <iostream> //prototype template <template <class> class ... _PolicyTs> struct GenHierarchy; //specialization for N policies constructs inheritance hierarchy template <template <class> class _HeadPolicyT, template <class> class ... _TailPolicyTs> struct GenHierarchy<_HeadPolicyT, _TailPolicyTs...> : _HeadPolicyT < GenHierarchy<_TailPolicyTs...> > {}; //inheritance hierarchy terminator and base class for concrete implementations template <> struct GenHierarchy < > {}; //dance behavior policies template <typename _ParentT> struct DanceA : _ParentT{ void Dance(){ std::cout << __FUNCTION__ << std::endl; } }; template <typename _ParentT> struct DanceB : _ParentT{ void Dance(){ std::cout << __FUNCTION__ << std::endl; } }; template <typename _ParentT> struct DanceC : _ParentT{ void Dance(){ std::cout << __FUNCTION__ << std::endl; } }; //joke behavior policies template <typename _ParentT> struct JokeA : _ParentT{ void Joke(){ std::cout << __FUNCTION__ << std::endl; } }; template <typename _ParentT> struct JokeB : _ParentT{ void Joke(){ std::cout << __FUNCTION__ << std::endl; } }; template <typename _ParentT> struct JokeC : _ParentT{ void Joke(){ std::cout << __FUNCTION__ << std::endl; } }; //sing behavior policies template <typename _ParentT> struct SongA : _ParentT{ void Sing(){ std::cout << __FUNCTION__ << std::endl; } }; template <typename _ParentT> struct SongB : _ParentT{ void Sing(){ std::cout << __FUNCTION__ << std::endl; } }; template <typename _ParentT> struct SongC : _ParentT{ void Sing(){ std::cout << __FUNCTION__ << std::endl; } }; //combine some behavior policies into concrete types using BozoTheClown = GenHierarchy < DanceA, JokeB, SongC > ; using HowdyDoody = GenHierarchy < DanceB, JokeA, SongA > ; using RedButtons = GenHierarchy < DanceC, JokeC, SongB > ; template <typename _Ty> void Entertain(_Ty oEntertainer){ oEntertainer.Sing(); oEntertainer.Dance(); oEntertainer.Joke(); } int main(){ Entertain(BozoTheClown()); Entertain(HowdyDoody()); Entertain(RedButtons()); return 0; } In the above example the BozoTheClown declaration is a short hand of effectively the following: struct BozoTheClown : DanceA<JokeB<SongC<GenHierarchy<>>>>{}; This is identical to: struct GenHierarchy{}; struct SongC : GenHierarchy{ void Sing(){ std::cout << __FUNCTION__ << std::endl; } }; struct JokeB : SongC{ void Joke(){ std::cout << __FUNCTION__ << std::endl; } }; struct DanceA : JokeB{ void Dance(){ std::cout << __FUNCTION__ << std::endl; } }; struct BozoTheClown : DanceA{}; The behavior policies must follow this concept: template <typename _ParentT> struct Base : _ParentT