Effective C++ Item 35 考虑 virtual 函数以外的实现

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie

1.virtual 函数版本

class GameCharacter{
public:
	virtual int healthValue() const; //返回人物的健康指数, derived classes 可重新定义它
};

2.使用 non-virtual interface 手法,那是 Template Method 设计模式的一种特殊形式。

让客户通过 public non-virtual 成员函数间接调用 private virtual 函数

class GameCharacter{
public:
	int healthValue() const // Item 36 derived classes不重新定义它
	{
		//...
		int retVal = doHealthValue();
		//...
		return retVal;
	}
private:
	virtual int doHealthValue() const //derive classes 可重新定义它
	{
		//...  缺省算法
	}
};

3.将 virtual 函数替换为“函数指针成员变量”,这是 Strategy 设计模式的一种分解表现形式。

优点:每天个对象可各自自己的健康计算函数、可在运行期改变计算函数

缺点:可能必须降低 GameCharacter 封装性。例如 声明 non-member 函数为 friends 或为其实现的某一部分提供 public 访问函数

//1.藉由 Function Pointers 实现 Strategy 模式

int defaultHealthCalc(const GameCharacter &gc);<span style="font-family: Arial, Helvetica, sans-serif;">//计算健康指数的缺省算法</span>

class GameCharacter{
public:
	typedef int (*HealthCalcFunc)(const GameCharacter);
	explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc) : healthFunc(hcf){}
	int healthValue() const{
		return healthFunc(*this);
	}
	//...
private:
	HealthCalcFunc healthFunc;
};
//2.藉由 tr1::function 完成 Strategy 模式
//以 tr1::function 成员变量替换 virtual 函数,因而允许使用任何可调用物(callable entity)
搭配一个兼容于需求的签名式。这也是 Strategy 设计模式的某种形式。

class GameCharacter;
int defaultHealthCalc(const GameCharacter &gc);
class GameCharacter{
public:
	//HealthCalcFunc 可以是任何“可调用物”,可被调用并被接受任何兼容于 GameCharacter 之物,返回任何兼容于 int的东西
	typedef std::tr1::function<int (const GameCharacter&)> HealthCalcFunc;
	explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc) : healthFunc(hcf){}
	int healthValue() const{
		return healthFunc(*this);
	}
	//...
private:
	HealthCalcFunc healthFunc;
};

4.将继承体系内的 virtual 函数替换为另一个继承体系内的 virtual 函数。这是 Strategy 设计模式

的传统实现手法。

class GameCharacter;
class HealthCalcFunc{
public:
	//...
	virtual int calc(const GameCharacter &gc) const{...}
};

HealthCalcFunc defaultHealthCalc;
class GameCharacter{
public:
	explicit GameCharacter(HealthCalcFunc *phcf = &defaultHealthCalc) : pHealthCalc(phhcf){}
	int healthValue() const {return pHealthCalc->calc(*this);}
private:
	HealthCalcFunc *pHealthCalc;
};

Effective C++ Item 35 考虑 virtual 函数以外的实现

时间: 2024-10-12 11:14:40

Effective C++ Item 35 考虑 virtual 函数以外的实现的相关文章

读书笔记 effective c++ Item 35 考虑虚函数的替代者

1. 突破思维——不要将思维限定在面向对象方法上 你正在制作一个视频游戏,你正在为游戏中的人物设计一个类继承体系.你的游戏处在农耕时代,人类很容易受伤或者说健康度降低.因此你决定为其提供一个成员函数,healthValue,返回一个整型值来表明一个人物的健康度.因为不同的人物会用不同的方式来计算健康度,将healthValue声明为虚函数看上去是一个比较明显的设计方式: 1 class GameCharacter { 2 public: 3 4 virtual int healthValue()

Effective C++ 条款35 考虑virtual函数以外的其他选择

1. 在一个继承层次中,不同的类要实现同一接口的不同实现,最先想到的可能是虚函数,假设一个存在一个继承体系,这个集成体系中的每一层都需要一个名为fun函数,那么可能会像这样实现: clase Base{ public: ... virtual fun(int num){...} private: ... } class Derived:public Base{ public: ... virtual fun(int num){} private: ... } 但除了将fun设为虚函数,还有其他选

Effective C++ Item 45 运用成员函数模板接收所有兼容类型

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:请使用 member function templates(成员函数模板)生成"可接受所有兼容类型"的函数 示例:泛化 copy 构造函数 temmplate<typename T> class SmartPtr{ public: template<typename U> SmartPtr(const SmartPtr<U> &o

Effective C++笔记_条款35 考虑virtual 函数以外的其他选择

因为其他的事情耽误了看书,现在将看的笔记记录下来. 1 class GameCharacter { 2 public: 3 virtual int healthValue() const; 4 }; 1. 藉由Non-Virtual Interface 手法实现 Template Method模式 (1)non-virtual interface(NVI): 令客户通过public non-virtual 成员函数间接调用private virtual函数 (2) virtual 函数的外覆器(

Effective JavaScript Item 28 不要依赖函数的toString方法

本系列作为Effective JavaScript的读书笔记. 在JavaScript中,函数对象上存在一个toString方法,它能够方便地将函数的源代码转换返回成一个字符串对象. (function(x) { return x + 1; }).toString(); // "function (x) {\n return x + 1;\n}" toString方法不仅仅会让一些黑客找到攻击的方法,而且该方法也存在严重的限制. 首先,toString方法的实现方式并没有被ECMASc

读书笔记 effective c++ Item 45 使用成员函数模板来接受“所有兼容类型”

智能指针的行为像是指针,但是没有提供加的功能.例如,Item 13中解释了如何使用标准auto_ptr和tr1::shared_ptr指针在正确的时间自动删除堆上的资源.STL容器中的迭代器基本上都是智能指针:当然,你不能通过使用“++”来将链表中的指向一个节点的内建指针移到下一个节点上去,但是list::iterator可以这么做. 1. 问题分析——如何实现智能指针的隐式转换 真正的指针能够做好的一件事情是支持隐式转换.派生类指针可以隐式转换为基类指针,指向非const的指针可以隐式转换成为

Effective JavaScript Item 35 使用闭包来保存私有数据

本系列作为EffectiveJavaScript的读书笔记. JavaScript的对象系统从其语法上而言并不鼓舞使用信息隐藏(Information Hiding).由于当使用诸如this.name.this.passwordHash的时候,这些属性默认的訪问级别就是public的.在不论什么位置都可以通过obj.name,obj.passwordHash来对这些属性进行訪问. 在ES5环境中,也提供了一些方法来更方便的訪问一个对象上全部的属性,比方Object.keys(),Object.g

《Effective C++》:条款35:考虑virtual函数以外的其他选择

条款35:考虑virtual函数以外的其他选择 条款35考虑virtual函数以外的其他选择 藉由Non-virtual Interface手法实现Template Method模式 藉由Function Pointers实现Strategy模式 藉由tr1function完成Strategy模式 古典的Strategy模式 摘要 virtual函数在派生中经常用到,在遇到一些问题时用virtual函数没问题,但是有时候我们应该思考一下是否有替代方案,以此来拓宽我们的视野. 假如现在正在写一个游

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

游戏中的人物伤害值计算问题. (一)方法(1):一般来讲可以使用虚函数的方法: class GameCharacter { public: virtual int healthValue() const; //返回人物的体力值,派生类可以做出修改 ... }; 这确实是一个显而易见的设计选择.但因为这样的设计过于显而易见,可能不会对其它可选方法给予足够的关注.我们来考虑一些处理这个问题的其它方法. (二)方法(2):使用NVI方法,在基类中使用一个公有的普通函数调用私有的虚函数. class G