条款35:考虑virtual函数以外的其他选择

/*条款35:考虑virtual函数以外的其他选择*/
#include<iostream>
using namespace std;
/*
class GameCharacter {//
public:
	virtual int healthValue()const;//返回人物的健康指数,子类会根据具体的人物角色来计算,而且这里并未声明为纯虚,暗示我们将会有个计算健康指针的缺省算法
	//但是不一定只有这一种实现方法
};
*/
//NVI手法实现template method模式
//一种思想流派主张虚函数应该几乎总是私有的,并且建议保留halthValue公有,但把它变成NV,并调用一个 private virtual
class GameCharacter {
public:
	int healthValue()const {//子类不重新定义它
		//。。。                 //事前工作 如加锁,验证,运转日志
		int retVal = doHealthValue();//做真正的工作
		//...                     //做一些事后工作如 释放互斥锁,再次验证
		return retVal;
	}
//private:
protected:
	virtual int doHealthValue()const {//外覆器wrapper
		//缺省算法,计算健康指数
	}
};/*优点 :1可以增加一些附带的必要工作
           2 基类保留诉说“函数何时被调用”的权利,而子类也被赋予了“如何实现机能”的控制能力(私有的虚函数,可以在子类中重新定义)
	缺点: 如果子类中需要调用这个虚函数就变的困难了,为了调用合法只能声明为保护,有时甚至必须是公开(具备多态性质的析构)这样就不能用NVI手法 了

  */
class ACharacter:public GameCharacter {
public:
	void doHealthValue() {

	}
	void funcallVfun(){
		GameCharacter::doHealthValue();
	}
};
//----------------------------function pointer 实现strategy模式
//这类设计主张“人物健康指数的计算与人物类型无关”可以把每个人物的构造函数接受一个函数指针,指向的函数做健康计算
class GameCharacter; //前置声明
int defaultHealthCalc(const GameCharacter&gc){}
class GameCharacter {
public:
	typedef int(*HealthCalcFunc)(const GameCharacter&);
	explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc):healthFunc(hcf){}
	int healthValue()const {
		return healthFunc(*this);
	}
	HealthCalcFunc healthFunc;
};
/*这个模式提供了某些有趣的弹性
  1 同一人物不同实体可以有不同的健康计算函数 如下
  2 某已知人物健康指数计算函数可在运行期变更 可以在基类中再添加 一个成员函数 用来替换当前健康计算函数
   换句话说健康指数计算不再是基类继承体系内的成员函数 这些计算函数并未特别访问要被计算的对象,如defaultHealthCalc 并未访问EvilBadGuy的non-public成分

*/
class EvilBadGuy:public GameCharacter {

};
int loseHealthQuickly(const GameCharacter&);//健康计算函数1,2
int loseHealthSlowly(const GameCharacter&);
EvilBadGuy ebg1(loseHealthQuickly);
EvilBadGuy ebg2(loseHealthSlowly);
//---------------tr1::funtion完成strategy模式
class GameCharacter;
int defaultHealthCalc(const GameCharacter& gc);
class GameCharacter {
public:
	typedef std::tr1::is_function<int(const GameCharacter&)>HealthCalcFunc;
	
	explicit GameCharacter(HealthCalcFunc hcf=defaultHealthCalc):healthFunc(hcf){}
	int healthValue()const {
		return healthFunc(*this);
	}
private:
	HealthCalcFunc healthFunc;
};
/*与函数指针不同的是 GameCharacter 持有一个函数对象 相当于一个指向函数的泛化的指针
 但它有更惊人的弹性

*/
short calcHealth(const GameCharacter&);//返回值 非int
struct HealCalculator {
	int operator()(const GameCharacter&)const {

	}
};
class GameLevel {
public:
	float health(const GameCharacter&)const;//计算健康 返回值非int

};
class EvilBadGuy:public GameCharacter{

}
class EyeCandyCharacter :public GameCharacter {
	//另一个人物类型 假设其构造函数与EvilBadGuy同
};
EvilBadGuy dbg1(calcHealth);//使用某个函数计算健康指数
EyeCandCharacter ecc1(HealthCalculator());//使用某个函数对象计算健康指数
GameLevel currentLevel;
EvilBadGuy ebg2(std::tr1::bind(&GameLevel::health, currentLevel, _1);
//上面没看懂。。。。
//古典strategy模式
//是将健康计算函数做成一个分离的继承体系中的虚成员函数
class GameCharacter;
class HealthCalcFunc {
public:
	virtual int calc(const GameCharacter&gc)const {

	}
};
HealthCalcFunc defaultHealthCalc;
class GameCharacter {
public:
	explicit GameCharacter(HealthCalFunc*phcf=&defaultHealthCalc):pHealthCalc(phcf){}//提供了默认构造
	int healthValue()const {
		return pHealthCalc->calc(*this);
	}
private:
	HealthCalcFunc*pHealthCalc;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值