條款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

 

***

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章