这种设计模式主要是利用模板和继承来实现的策略模式。
class demoClass
{
public:
void func(int type)
{
switch (type)
{
case 1:
func1(); break;
case 2:
func2(); break;
default:
break;
}
}
private:
void func1() { cout << "used func1" << endl; }
void func2() { cout << "used func1" << endl; }
};
//
template<typename T>
class demoClass:private T
{
public:
void func() {T::func()};
};
class func_policy1
{
protected:
void func() { cout << "used func1" << endl; }
};
class func_policy2
{
protected:
void func() { cout << "used func2" << endl; }
};
int main()
{
demoClass<func_policy1> demo;
demo.func();
system("pause");
return 0;
}
下面是维基百科上的demo, 思考一个问题,为什么LanguagePolicyEnglish里面的成员设计为protected, 其实一开始设计为public也可以,假如为public, 那么我们继承肯定用private, 因为HelloWorld和LanguagePolicy不是is-a关系,HelloWorld只是想用LanguagePolicy的实现,那么根据effective C++中的条款我们只能用private 继承,好像也没什么问题,但是有个问题是LanguagePolicy可以实例化一个对象,直接调用Message()函数,其实这个不符合理论要求,因为你只是一个实现策略,但是又不能把Message()函数设置为private, 因为这样子类就没法调用了,综上考虑设置为protected.
这里可以当做一个条款来记住,当一个类只是提供实现的时候,如果后面需要对齐做private 继承,那么就用protected 作为其成员属性。
#include <iostream>
#include <string>
template <typename OutputPolicy, typename LanguagePolicy>
class HelloWorld : private OutputPolicy, private LanguagePolicy {
public:
// Behavior method.
void Run() const {
// Two policy methods.
Print(Message());
}
private:
using LanguagePolicy::Message;
using OutputPolicy::Print;
};
class OutputPolicyWriteToCout {
protected:
template <typename MessageType>
void Print(MessageType&& message) const {
std::cout << message << std::endl;
}
};
class LanguagePolicyEnglish {
protected:
std::string Message() const { return "Hello, World!"; }
};
class LanguagePolicyGerman {
protected:
std::string Message() const { return "Hallo Welt!"; }
};
int main() {
// Example 1
using HelloWorldEnglish = HelloWorld<OutputPolicyWriteToCout, LanguagePolicyEnglish>;
HelloWorldEnglish hello_world;
hello_world.Run(); // Prints "Hello, World!".
// Example 2
// Does the same, but uses another language policy.
using HelloWorldGerman = HelloWorld<OutputPolicyWriteToCout, LanguagePolicyGerman>;
HelloWorldGerman hello_world2;
hello_world2.Run(); // Prints "Hallo Welt!".
}