0

在 Effective C++,第 3 版,第 173~175 页中,Scott Meyers 谈到了使用策略模式的虚拟函数的替代方案:

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类的构造函数需要一些函数,该函数接受与 a 兼容的参数const GameCharacter&并返回可转换为int.

这是否由中operator()定义的支持/实现struct HealthCalculator?我不太明白这里这个重载运算符的含义。

我这里的另一个问题是派生类的构造函数中的初始化列表通常只初始化其自身的数据成员(尽管我知道派生类的基础部分也被隐式初始化)。基类怎么会GameCharacter出现在派生类的初始化器中EyeCandyCharacter

4

2 回答 2

2

在你的第一个问题中:

我的问题是,EyeCandyCharacter 类的构造函数需要一些函数,该函数采用与 const GameCharacter& 兼容的参数并返回可转换为 int 的东西。...这是否由 struct HealthCalculator 中定义的 operator() 支持/实现?

是的,它受支持。你必须知道/记住那HealthCalculator是一个functor。它实现了operator ()“模拟”调用传统函数的语法。它operator ()接受 aconst GameCharacter&并返回 a int,这与EyeCandyCharacter(以及随后GameCharacter)想要的兼容。

在你的第二个问题中:

基类 GameCharacter 怎么会出现在派生类 EyeCandyCharacter 的初始化器中?

通过调用构造函数EyeCandyCharacter来初始化基类。不这样做会使' 的构造函数调用' 的默认构造函数,该构造函数未定义,因此会导致错误。GameCharacterGameCharacterEyeCandyCharacterGameCharacter


作为旁注,您现在可以在 C++11 中直接使用std::functionstd::tr1::function.

于 2013-05-21T04:14:29.553 回答
1

对于你的第二个问题:

我这里的另一个问题是派生类的构造函数中的初始化列表通常只初始化其自身的数据成员(尽管我知道派生类的基础部分也被隐式初始化)。基类 GameCharacter 怎么会出现在派生类 EyeCandyCharacter 的初始化器中?

不,如果您的基类没有default constructor定义,而是定义了其他构造函数,则必须调用基类构造函数来初始化基类成员。因为在这种情况下,编译不会default constructor为你生成一个。换句话说,

派生类的基础部分并不总是隐式初始化

于 2013-05-21T04:10:16.643 回答