zoukankan      html  css  js  c++  java
  • 条款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的使用
  • 相关阅读:
    μC/OS-II中使用软件定时器
    基于javafx的实训项目实战 —— 猿天气
    郑州轻工业大学软件学院计算机网络期末复习
    软件工程经济学结课报告——兰花智慧大棚监控系统可行性研究报告
    基于javafx实现一个简单的图片查看器
    数据结构之动态数组
    JSP技术
    JavaWeb实现上传下载
    windows下mysql编码问题
    基于socket的即时通信系统的设计与实现
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4889778.html
Copyright © 2011-2022 走看看