Qiang Xu
Qiang Xu

Reputation: 4803

overloaded operator() in c++ structure

In Effective C++, 3rd Edition, Page 173~175, Scott Meyers talked of alternatives to virtual functions using the strategy pattern:

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());

The last statement is to illustrate how to use a health calculation function object in the constructor of EyeCandyCharacter class.

My question is, the constructor of EyeCandyCharacter class requires some function that takes a parameter compatible with a const GameCharacter& and returns something convertible to an int.

Is this supported/implemented by operator() defined in struct HealthCalculator? I don't quite understand the meaning of this overloaded operator here.

Another question of mine here is that the initializer list in the constructor of the derived class usually only initializes the data members of itself (though I know the base part of the derived class is also intialized implicitly). How come the base class GameCharacter appears in the initializer of derived class EyeCandyCharacter?

Upvotes: 0

Views: 188

Answers (2)

Mark Garcia
Mark Garcia

Reputation: 17708

In your first question:

My question is, the constructor of EyeCandyCharacter class requires some function that takes a parameter compatible with a const GameCharacter& and returns something convertible to an int. ... Is this supported/implemented by operator() defined in struct HealthCalculator?

Yes, it is supported. You must know/remember that HealthCalculator is a functor. It implements the operator () to "simulate" the syntax of calling traditional functions. Its operator () takes a const GameCharacter& and returns an int, which is compatible with what EyeCandyCharacter (and subsequently GameCharacter) wants.

In your second question:

How come the base class GameCharacter appears in the initializer of derived class EyeCandyCharacter?

That initializes the base class of EyeCandyCharacter which is GameCharacter by calling GameCharacter's constructor. Not doing this makes EyeCandyCharacter's constructor call GameCharacter's default constructor, which isn't defined, and therefore will result in an error.


As a sidenote, you can now, in C++11, directly use std::function which have roughly the same functionality as std::tr1::function.

Upvotes: 2

taocp
taocp

Reputation: 23644

For your second question:

Another question of mine here is that the initializer list in the constructor of the derived class usually only initializes the data members of itself (though I know the base part of the derived class is also intialized implicitly). How come the base class GameCharacter appears in the initializer of derived class EyeCandyCharacter?

No, if your base class does not have default constructor defined, but has other constructors defined instead, you have to call based class constructor to initialize base class members. Since in this case, compile will not generate a default constructor for you. In other words,

the base part of the derived class is NOT always initialized implicitly

Upvotes: 1

Related Questions