关于c++ class中virtual 函数的几种替代方案

1 NVI (Non-Virtual Interface)

看下面的类继承关系:

class GameCharactor
{
public:
virtual void CalculateScore(const GameCharactor& charactor);
};
class ACharactor : public GameCharactor
{
public:
virtual void CalculateScore(const GameCharactor& charactor);
};
class BCharactor : public GameCharactor
{
virtual void CalculateScore(const GameCharactor& charactor);
};

我们用基类来抽象游戏中的一个角色,这个角色有一个计算自身得分的函数CalculateScore(),由于继承自此基类的每一个子类很可能都有他们自己的计算得分的方法,所以我们在设计的时候首先想到,将这个计算得分的函数定义为虚函数,子类继承并重写之。但是这样就存在两个问题,其一是可扩展性不高,假设每个子类在调用得分函数之前、之后需要做一些各自的其他操作呢,所以将基类改为如下设计,用Non-Virtual的函数取代Virtual函数作为提供给用户的借口:

class GameCharactor
{
public:
void GetScore(){ CalculateScore(*this); }
private:
virtual void CalculateScore(const GameCharactor& charactor);
};

第二个问题是如果同一个子类的不同对象需要不同的计算得分的函数呢?所以在此引入第二种方案:

2、在参数中引入函数指针

typedef void (*GetScore)(cosnt GameCharactor&) ;

void DefaultSocre(const GameCharactor& charactor){..........}

class GameCharactor
{
public:

GameCharactor(GetSocre getscore = DefaultSocre):GetCharactorScore(getscore ){}
void GetScore(){ GetCharactorScore(*this);}
private:

GetSocre GetCharactorScore;
};

这里通过传入函数指针的形式,可实现更细粒度的多态,并且还有一个好处就是可以动态改变每一个对象实例的计算得分的函数,比如可以通过SetScoreFunction()借口来实现。

3、上面第二种参数也可以通过传入对象指针的方式来实现,UML图如下:


总结:

虚函数可以用来实现继承于同一基类的不通子类之间的多态,通过引入指针或对象指针的方式可以实现更细粒度的多态,即同一子类不同对象之间的多态。上述三种方式中的后两种方式是strategy设计模式的应用。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值