【Effective C++】virtual function 的替代方案

本文探讨了在 C++ 中避免使用 virtual 函数的替代设计方案,包括 Non-virtual Interface 实现的模板方法和利用 function pointers 或仿函数实现的策略模式。通过这些方法,可以更好地控制对象行为并提高代码灵活性。Non-virtual Interface 允许在调用 virtual 函数前后添加额外操作,而策略模式则将算法封装为独立的实体,允许在运行时动态改变行为。仿函数进一步增强了策略模式的灵活性,能够适应各种可调用类型。
摘要由CSDN通过智能技术生成

假设你正在为一个游戏软件中的人物设计一个继承体系。每个人物都有一个血量值,且不同的人物之间血量的变化方式也不一样,基于这样的目的,你可能会想着这样设计一个基类:

class GameCharacter
{
   
public:
	virtual int healthValue() const;	//返回人物当前的血量
	//...
};

具体的人物类会继承这个 GameCharacter 基类,可以在其中对血量的计算函数 healthValue() 进行重写。在基类中,并没有将 healthValue() 函数设置为 pure virtual function ,意味着在基类中会有一个缺省的实现。

这是一种再自然不过的设计方式。实际上,我们也可以考虑其他的设计方案。


Non-virtual Interface 实现模板方法


在 C++ 的设计流派中,有一个流派主张 virtual 函数应该几乎总是成为 private 函数。他们建议,将对外接口设计为 non-virtual,并且对内调用一个 private virtual 函数进行实际的动作,如下面这样:

class GameCharacter
{
   
public:
	virtual int healthValue() const
	{
   
		//...							//做一些事前动作
		int result = doHealthValue();
		//...							//做一些事后动作
		return result;
	}
	//...

private:
	virtual int doHealthValue() const	// derived class 可以重新定义
	{
   
		//...							//计算人物血量的缺省算法
	}
};

这种,让客户端通过 public non-virtual 成员函数间接调用 private virtual 成员函数 的方法,称为 non-virtual interface (NVI),它是23种设计模式中模板方法(Template Method) 的一种特殊的表现形式。
NVI 的一个优点就是代码中所展现的,可以在 virtual function 执行之前和之后做一些额外的事情。比如说可以在事前 locking a mutex,然后在事后释放。


利用 function pointers 实现策略模式

这一种替代方案是基于这样一种考虑:血量的计算和人物的类型并没有关系,healthValue() 函数的执行,对于不同的人物类型来说,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值