2013-05-21 37 views
0

在有效的C++,第3版,第173〜175,斯科特邁爾斯談到使用策略模式替代虛函數:重載操作(c)中++結構

class GameCharacter; 
int defaultHealthCalc(const GameCharacter& gc); 

class GameCharacter { 
public: 
    typedef std::tr1::function<int (const GameCharacter&)> HealthCalcFunc; 
    explicit GameCharacter(HealthCalcFUnc hcf = defaultHealthCalc) 
    : healthFunc(hcf) 
    {} 

    int healthValue const 
    { return healthFunc(*this) } 
    ... 
private: 
    HealthCalcFunc healthFunc; 
}; 
... 
struct HealthCalculator { 
    int operator()(const GameCharacter&) const 
    { ... } 
}; 
... 
class EyeCandyCharacter: public GameCharacter { 
    explicit EyeCandyCharacter(HealthCalcFunc hcf=defaultHealthCalc) 
    :GameCharacter(hcf) 
    { ... } 
    ... 
} 
... 
EyeCcandyCharacter ecc(HealthCalculator()); 

最後一個語句是說明如何在EyeCandyCharacter類的構造函數中使用健康計算函數對象。

我的問題是,EyeCandyCharacter類的構造函數需要一些函數,它需要一個兼容const GameCharacter&的參數並返回可轉換爲int的東西。

這是由struct HealthCalculator中定義的operator()支持/實施的嗎?我不太明白這個重載操作符的含義。

這裏的另一個問題是,派生類的構造函數中的初始化列表通常只初始化它本身的數據成員(儘管我知道派生類的基本部分也是隱含地初始化的)。基類GameCharacter如何出現在派生類EyeCandyCharacter的初始化程序中?

回答

2

在你的第一個問題:

我的問題是,EyeCandyCharacter類的構造函數需要 某些函數需要一個參數兼容const GameCharacter &並返回可轉換爲int的內容。 ...由結構式 HealthCalculator中定義的operator()支持/實現的 ?

是的,它被支持。你必須知道/記住HealthCalculatorfunctor。它實現了operator()來「模擬」調用傳統函數的語法。其operator()需要const GameCharacter&並且返回int,其與EyeCandyCharacter(以及隨後的GameCharacter)想要的兼容。

在你的第二個問題:

怎麼來的基類GameCharacter出現在 派生類EyeCandyCharacter的初始化?

即通過調用GameCharacter的構造函數初始化的基類的EyeCandyCharacter這是GameCharacter。不這樣做使得EyeCandyCharacter的構造函數調用GameCharacter的默認構造函數,該函數未定義,因此會導致錯誤。


作爲旁註,你現在可以,在C++ 11,直接使用std::function具有大致相同的功能std::tr1::function

1

對於你的第二個問題:

我的另一個問題在這裏是在派生類的構造函數初始化列表通常只初始化自身的數據成員(雖然我知道派生的底座部分類也是初始化的)。 爲什麼基類GameCharacter出現在派生類EyeCandyCharacter的初始化程序中?

沒有,如果default constructor定義,但不是規定的其他構造的基礎類沒有,你必須調用基於類的構造函數初始化基類成員。由於在這種情況下,編譯將不會爲您生成default constructor。換句話說,

派生類的底座部分是總是初始化隱含