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

 

  

模板方法模式

#include <iostream>
using namespace std;

class GameCharacter
{
public :
    int healthValue() const
    {
        //... 做一些事前工作
        int rtnValue = doHealthValue();
        //... 做一些事后工作

        return rtnValue;
    }
private:
    virtual int doHealthValue() const
    {
        //缺省计算健康方法
        cout << "缺省计算健康方法\n";
        return 0;
    }
};

class Character01 : public GameCharacter
{
    //...
private:
    virtual int doHealthValue() const
    {
        cout << "Character01 计算健康方法\n";
        return 1;
    }
};
class Character02 : public GameCharacter
{
    //...
private:
    virtual int doHealthValue() const
    {
        cout << "Character02 计算健康方法\n";
        return 2;
    }
};
class Character03 : public GameCharacter
{
    //...

};

// 以引用或指针方式传递参数,才会多态
void displayHealth(GameCharacter& p){
    p.healthValue();
}

int main(){

    Character01 c1;
    displayHealth(c1);
    Character02 c2;
    displayHealth(c2);
    Character03 c3;
    displayHealth(c3);

    return 0;
}

/*
Character01 计算健康方法
Character02 计算健康方法
缺省计算健康方法
*/
View Code

 

 

用 函数指针 实现 Strategy

#include <iostream>
using namespace std;

// 用 函数指针 实现 Strategy

class GameCharacter;

int defaultHealthCalc(const GameCharacter& gc)
{
    cout << "缺省计算健康方法\n";
    return 0;
}

int loseHealthQuicklyCalc(const GameCharacter& gc)
{
    cout << "快速掉血\n";
    return 0;
}

int loseHealthSlowlyCalc(const GameCharacter& gc)
{
    cout << "缓慢掉血\n";
    return 0;
}



class GameCharacter
{
public:
    typedef int(*HealthCalcFunc) (const GameCharacter&);//函数指针类型
    GameCharacter(HealthCalcFunc hcf = defaultHealthCalc)
        : healthCalcFunc(hcf)
    {
    }
    int healthValue() const
    {
        //... 做一些事前工作
        int rtnValue = healthCalcFunc(*this);
        //... 做一些事后工作

        return rtnValue;
    }
private:
    HealthCalcFunc healthCalcFunc;
};

class Character01 : public GameCharacter
{
public:
    Character01(HealthCalcFunc hcf = defaultHealthCalc)
        : GameCharacter(hcf)
    {
    }
    //...
};
class Character02 : public GameCharacter
{
public:
    Character02(HealthCalcFunc hcf = defaultHealthCalc)
        : GameCharacter(hcf)
    {
    }
    //...
};

class Character03 : public GameCharacter
{
    //...
};


// 以引用或指针方式传递参数,才会多态
void displayHealth(GameCharacter& p){
    p.healthValue();
}


int main(){
    Character01 c1(loseHealthQuicklyCalc);
    displayHealth(c1);
    Character02 c2(loseHealthSlowlyCalc);
    displayHealth(c2);
    Character03 c3;
    displayHealth(c3);
    Character02 c4;
    displayHealth(c4);
    return 0;
}
/*
快速掉血
缓慢掉血
缺省计算健康方法
缺省计算健康方法
*/
View Code

 

用 tr1::function 实现 Strategy

#include <iostream>
#include <functional>
using namespace std;

// 用 tr1::function 实现 Strategy

class GameCharacter;

int defaultHealthCalc(const GameCharacter& gc)
{
    cout << "缺省计算健康方法\n";
    return 0;
}

int loseHealthQuicklyCalc(const GameCharacter& gc)
{
    cout << "快速掉血\n";
    return 0;
}

int loseHealthSlowlyCalc(const GameCharacter& gc)
{
    cout << "缓慢掉血\n";
    return 0;
}

//函数对象 (函数符)
class LoseHealthSlowlyCalc
{
public:
    int operator()(const GameCharacter& gc)
    {
        cout << "缓慢掉血2\n";
        return 0;
    }
};



class GameCharacter
{
public:
    //std::tr1::function 或者 std::function 都可以。该变量表示 任何的可调用之物
    typedef std::function< int (const GameCharacter&) > HealthCalcFunc; 
    GameCharacter(HealthCalcFunc hcf = defaultHealthCalc)
        : healthCalcFunc(hcf)
    {
    }
    int healthValue() const
    {
        //... 做一些事前工作
        int rtnValue = healthCalcFunc(*this);
        //... 做一些事后工作

        return rtnValue;
    }
private:
    HealthCalcFunc healthCalcFunc;
};

class Character01 : public GameCharacter
{
public:
    Character01(HealthCalcFunc hcf = defaultHealthCalc)
        : GameCharacter(hcf)
    {
    }
    //...
};
class Character02 : public GameCharacter
{
public:
    Character02(HealthCalcFunc hcf = defaultHealthCalc)
        : GameCharacter(hcf)
    {
    }
    //...
};

class Character03 : public GameCharacter
{
    //...
};


// 以引用或指针方式传递参数,才会多态
void displayHealth(GameCharacter& p){
    p.healthValue();
}


int main(){
    Character01 c1(loseHealthQuicklyCalc);
    displayHealth(c1);
    Character02 c2(loseHealthSlowlyCalc);
    displayHealth(c2);
    Character03 c3;
    displayHealth(c3);
    //使用Lambda表达式
    Character02 c4([](const GameCharacter& gc) -> int
        {
            cout << "特殊的,健康计算方法,Lambda表达式\n";
            return 0;
        }
    );
    displayHealth(c4);
    //使用函数对象
    LoseHealthSlowlyCalc slowLoseHealth;
    Character01 c5(slowLoseHealth);
    displayHealth(c5);
    return 0;
}
/*
快速掉血
缓慢掉血
缺省计算健康方法
特殊的,健康计算方法,Lambda表达式
缓慢掉血2
*/
View Code

 

用 古典的 Strategy 策略模式,即用继承实现方法簇

#include <iostream>
#include <functional>
using namespace std;

// 用 古典的 Strategy 策略模式,即用继承实现方法簇

class GameCharacter;

class HealthCalc
{
public:
    virtual int calc(const GameCharacter& gc)
    {
        cout << "缺省计算健康方法\n";
        return 0;
    }
};

class SlowHealthCalc : public HealthCalc
{
public:
    virtual int calc(const GameCharacter& gc)
    {
        cout << "缓慢掉血\n";
        return 0;
    }
};
class QuickHealthCalc : public HealthCalc
{
public:
    virtual int calc(const GameCharacter& gc)
    {
        cout << "快速掉血\n";
        return 0;
    }
};

HealthCalc defaultHealthCalc;

class GameCharacter
{
public:
    
    GameCharacter(HealthCalc* phc = &defaultHealthCalc)
        : pHealthCalc(phc)
    {
    }
    int healthValue() const
    {
        //... 做一些事前工作
        int rtnValue = pHealthCalc->calc(*this);
        //... 做一些事后工作

        return rtnValue;
    }
private:
    HealthCalc* pHealthCalc;
};

class Character01 : public GameCharacter
{
public:
    Character01(HealthCalc* phc = &defaultHealthCalc)
        : GameCharacter(phc)
    {
    }
    //...
};
class Character02 : public GameCharacter
{
public:
    Character02(HealthCalc* phc = &defaultHealthCalc)
        : GameCharacter(phc)
    {
    }
    //...
};

class Character03 : public GameCharacter
{
    //...
};


// 以引用或指针方式传递参数,才会多态
void displayHealth(GameCharacter& p){
    p.healthValue();
}


int main(){
    QuickHealthCalc hc1;
    Character01 c1(&hc1);
    displayHealth(c1);
    SlowHealthCalc hc2;
    Character02 c2(&hc2);
    displayHealth(c2);
    Character03 c3;
    displayHealth(c3);
    
    return 0;
}
/*
快速掉血
缓慢掉血
缺省计算健康方法
*/
View Code

 

***

posted @ 2022-11-22 17:37  htj10  阅读(16)  评论(0编辑  收藏  举报
TOP