2013-05-21 36 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。换句话说,

派生类的底座部分是总是初始化隐含