条款35:考虑virtual函数以外的其他选择
模板方法模式
#include <iostream> using namespace std; class GameCharacter { public : int healthValue() const { //... 做一些事前工作 int rtnValue = doHealthValue(); //... 做一些事后工作 return rtnValue; } private: virtual int doHealthValue() const { //缺省计算健康方法 cout << "缺省计算健康方法\n"; return 0; } }; class Character01 : public GameCharacter { //... private: virtual int doHealthValue() const { cout << "Character01 计算健康方法\n"; return 1; } }; class Character02 : public GameCharacter { //... private: virtual int doHealthValue() const { cout << "Character02 计算健康方法\n"; return 2; } }; class Character03 : public GameCharacter { //... }; // 以引用或指针方式传递参数,才会多态 void displayHealth(GameCharacter& p){ p.healthValue(); } int main(){ Character01 c1; displayHealth(c1); Character02 c2; displayHealth(c2); Character03 c3; displayHealth(c3); return 0; } /* Character01 计算健康方法 Character02 计算健康方法 缺省计算健康方法 */
用 函数指针 实现 Strategy
#include <iostream> using namespace std; // 用 函数指针 实现 Strategy class GameCharacter; int defaultHealthCalc(const GameCharacter& gc) { cout << "缺省计算健康方法\n"; return 0; } int loseHealthQuicklyCalc(const GameCharacter& gc) { cout << "快速掉血\n"; return 0; } int loseHealthSlowlyCalc(const GameCharacter& gc) { cout << "缓慢掉血\n"; return 0; } class GameCharacter { public: typedef int(*HealthCalcFunc) (const GameCharacter&);//函数指针类型 GameCharacter(HealthCalcFunc hcf = defaultHealthCalc) : healthCalcFunc(hcf) { } int healthValue() const { //... 做一些事前工作 int rtnValue = healthCalcFunc(*this); //... 做一些事后工作 return rtnValue; } private: HealthCalcFunc healthCalcFunc; }; class Character01 : public GameCharacter { public: Character01(HealthCalcFunc hcf = defaultHealthCalc) : GameCharacter(hcf) { } //... }; class Character02 : public GameCharacter { public: Character02(HealthCalcFunc hcf = defaultHealthCalc) : GameCharacter(hcf) { } //... }; class Character03 : public GameCharacter { //... }; // 以引用或指针方式传递参数,才会多态 void displayHealth(GameCharacter& p){ p.healthValue(); } int main(){ Character01 c1(loseHealthQuicklyCalc); displayHealth(c1); Character02 c2(loseHealthSlowlyCalc); displayHealth(c2); Character03 c3; displayHealth(c3); Character02 c4; displayHealth(c4); return 0; } /* 快速掉血 缓慢掉血 缺省计算健康方法 缺省计算健康方法 */
用 tr1::function 实现 Strategy
#include <iostream> #include <functional> using namespace std; // 用 tr1::function 实现 Strategy class GameCharacter; int defaultHealthCalc(const GameCharacter& gc) { cout << "缺省计算健康方法\n"; return 0; } int loseHealthQuicklyCalc(const GameCharacter& gc) { cout << "快速掉血\n"; return 0; } int loseHealthSlowlyCalc(const GameCharacter& gc) { cout << "缓慢掉血\n"; return 0; } //函数对象 (函数符) class LoseHealthSlowlyCalc { public: int operator()(const GameCharacter& gc) { cout << "缓慢掉血2\n"; return 0; } }; class GameCharacter { public: //std::tr1::function 或者 std::function 都可以。该变量表示 任何的可调用之物 typedef std::function< int (const GameCharacter&) > HealthCalcFunc; GameCharacter(HealthCalcFunc hcf = defaultHealthCalc) : healthCalcFunc(hcf) { } int healthValue() const { //... 做一些事前工作 int rtnValue = healthCalcFunc(*this); //... 做一些事后工作 return rtnValue; } private: HealthCalcFunc healthCalcFunc; }; class Character01 : public GameCharacter { public: Character01(HealthCalcFunc hcf = defaultHealthCalc) : GameCharacter(hcf) { } //... }; class Character02 : public GameCharacter { public: Character02(HealthCalcFunc hcf = defaultHealthCalc) : GameCharacter(hcf) { } //... }; class Character03 : public GameCharacter { //... }; // 以引用或指针方式传递参数,才会多态 void displayHealth(GameCharacter& p){ p.healthValue(); } int main(){ Character01 c1(loseHealthQuicklyCalc); displayHealth(c1); Character02 c2(loseHealthSlowlyCalc); displayHealth(c2); Character03 c3; displayHealth(c3); //使用Lambda表达式 Character02 c4([](const GameCharacter& gc) -> int { cout << "特殊的,健康计算方法,Lambda表达式\n"; return 0; } ); displayHealth(c4); //使用函数对象 LoseHealthSlowlyCalc slowLoseHealth; Character01 c5(slowLoseHealth); displayHealth(c5); return 0; } /* 快速掉血 缓慢掉血 缺省计算健康方法 特殊的,健康计算方法,Lambda表达式 缓慢掉血2 */
用 古典的 Strategy 策略模式,即用继承实现方法簇
#include <iostream> #include <functional> using namespace std; // 用 古典的 Strategy 策略模式,即用继承实现方法簇 class GameCharacter; class HealthCalc { public: virtual int calc(const GameCharacter& gc) { cout << "缺省计算健康方法\n"; return 0; } }; class SlowHealthCalc : public HealthCalc { public: virtual int calc(const GameCharacter& gc) { cout << "缓慢掉血\n"; return 0; } }; class QuickHealthCalc : public HealthCalc { public: virtual int calc(const GameCharacter& gc) { cout << "快速掉血\n"; return 0; } }; HealthCalc defaultHealthCalc; class GameCharacter { public: GameCharacter(HealthCalc* phc = &defaultHealthCalc) : pHealthCalc(phc) { } int healthValue() const { //... 做一些事前工作 int rtnValue = pHealthCalc->calc(*this); //... 做一些事后工作 return rtnValue; } private: HealthCalc* pHealthCalc; }; class Character01 : public GameCharacter { public: Character01(HealthCalc* phc = &defaultHealthCalc) : GameCharacter(phc) { } //... }; class Character02 : public GameCharacter { public: Character02(HealthCalc* phc = &defaultHealthCalc) : GameCharacter(phc) { } //... }; class Character03 : public GameCharacter { //... }; // 以引用或指针方式传递参数,才会多态 void displayHealth(GameCharacter& p){ p.healthValue(); } int main(){ QuickHealthCalc hc1; Character01 c1(&hc1); displayHealth(c1); SlowHealthCalc hc2; Character02 c2(&hc2); displayHealth(c2); Character03 c3; displayHealth(c3); return 0; } /* 快速掉血 缓慢掉血 缺省计算健康方法 */
***
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。