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


    有一部分人总是主张virtual函数几乎总应该是private:例如下面这个例子,例子时候游戏,游戏里面的任务都拥有健康值这一属性:

    class GameCharacter{
    public:
        int healthValue()const{
            ...
            int retVal = doHealthValue();
            ...
            return retVal;
        }
    private:
        virtual int doHealthValue() const
        {
        }//上面的这个non-virtual函数实际上是virtual函数的一个外覆器
    };
    这里使用一个外覆器的好处是:了一使用外覆器在调用虚函数之前以及之后分别做一些特定的操作。例如锁定mutex或者是解锁mutex这种事。
    上面这个可以称为Template Method模式的一种特例:
     
    还有用function Pointer实现的strategy模式;假如healthValue的规则有一个内含的成员healthFunc来进行指定(这样降低了耦合)
     1 class GameCharacter;
     2 int defaultHealthCalc(const GameCharacter & gc);
     3 class GameCharacter{
     4 public:
     5     typedef std::function<int (const GameCharacter & )>  HealCalcFunc
     6     explicit GameCharacter(HealCalcFunc hcf = defaultHealthCalc)
     7     :healthFunc(hcf){}
     8     int healthValue() const
     9     {return healthFunc(* this); }
    10     ...
    11 private:
    12     HealCalcFunc healthFunc;
    13 };

    实际上,这个typedef带来的弹性是很大的:

     1 short clacHealth(const GameCharacter &);
     2 //或者是一个函数对象
     3 struct HealCalculater{
     4 public:
     5     float operator()(const GameCharacters & gc) const ;
     6 };
     7 //或者是一个成员函数。
     8 class GameLevel{
     9 public:
    10     float Health(const GameCharacters)const;
    11 };
    12 GameCharacters character1(clacHealth);
    13 GameCharacters character2(HealCalculater());
    14 GameLevel levelObj;
    15 GameCharacters character3(std::bind(&GameLevel::health, levelObj, _1));//不记得这样写对不对,待查
    上面这些例子都可以正确通过切运行,这说明这种方式给我们带来的弹性是很大的。
     
    不仅如此,这种方式在延伸一下就可以设计出来典型的策略模式:
     1 class HealCalculater;
     2 class GameCharacter;
     3 int defaultHealthCalc(const GameCharacter & gc);
     4 class GameCharacter{
     5 public:
     6     typedef std::function<int (const GameCharacter & )>  HealCalcFunc
     7     explicit GameCharacter(HealCalcFunc hcf = defaultHealthCalc)
     8     :healthFunc(hcf){}
     9     int healthValue() const
    10     {return healthFunc(* this); }
    11     ...
    12 private:
    13     HealCalcFunc * phealthFunc;
    14 };
    15 HealCalculater{
    16 public : 
    17     virtual int calc(const GameCharacter & gc)const
    18     {}    //也可以只声明一个接口
    19 }
    小结:
        virtual函数的替代方案包括nv1手法以及strategy设计模式等多种形式
        将机能从成员函数移动到class外部函数,带来的缺点是非成员函数无法访问class的non-public成员
        注意function已经bind的使用
  • 相关阅读:
    9.11 eventbus
    9.10,,,实现new instanceof apply call 高阶函数,偏函数,柯里化
    9.9 promise实现 写完了传到gitee上面了,这里这个不完整
    9.5cors配置代码
    9.5 jsonp 实现
    9.5 http tcp https总结
    9.3 es6 class一部分 and es5 class 发布订阅
    8.30 cookie session token jwt
    8.30vue响应式原理
    warning: LF will be replaced by CRLF in renard-wx/project.config.json. The file will have its original line endings in your working directory
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4889778.html
Copyright © 2020-2023  润新知