在有效的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类的构造函数需要一些函数,该函数需要与const GameCharacter&兼容的参数并返回可转换为int的值。

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

我的另一个问题是,派生类的构造函数中的初始化程序列表通常仅初始化其自身的数据成员(尽管我知道派生类的基部也被隐式初始化)。基类GameCharacter如何出现在派生类EyeCandyCharacter的初始化程序中?

最佳答案

在第一个问题中:


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


是的,它受支持。您必须知道/记住HealthCalculatorfunctor。它实现了operator ()以“模拟”调用传统函数的语法。它的operator ()接受一个const GameCharacter&并返回一个int,它与EyeCandyCharacter(以及随后的GameCharacter)所需内容兼容。

在第二个问题中:


  基类GameCharacter如何出现在的初始化程序中
  派生类EyeCandyCharacter?


这将通过调用EyeCandyCharacter的构造函数来初始化GameCharacter的基类,即GameCharacter。不这样做会导致EyeCandyCharacter的构造函数调用GameCharacter的默认构造函数(未定义),因此将导致错误。



附带说明,您现在可以在C ++ 11中直接使用std::function,其功能与std::tr1::function大致相同。

10-08 19:53