跳轉到內容

更多 C++ 慣用法/層次結構生成

來自華夏公益教科書,開放的世界,開放的書籍

層次結構生成

[編輯 | 編輯原始碼]

生成由各種行為策略組成的具體類

當一個解決方案需要許多不同的實現,這些實現可以以多種方式組合,每個實現共享或不共享各種裝飾,傳統的解決方案是多重繼承,這會導致各種問題。層次結構生成是一種模式,透過它,可以連續繼承各種基類來避免多重繼承。

解決方案和示例程式碼

[編輯 | 編輯原始碼]
#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;
}

在上面的示例中,BozoTheClown 宣告是以下內容的簡寫

struct BozoTheClown : DanceA<JokeB<SongC<GenHierarchy<>>>>{};

這與以下內容相同

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{};

行為策略必須遵循此概念

template <typename _ParentT> struct Base : _ParentT
華夏公益教科書