My goal is to have a C++ Implementation of the Strategy Pattern without manual memory allocation. I do not feel like it ought to be necessary in the example that I give, conceptually speaking. Also, manual memory management is prone to errors. Keep in mind that my example is just an MWE, in reality all objects are more complicated and manual memory management often introduces bugs.
In the below example, the class Base
needs to be given a Strategy
to be constructed, which it will use to produce the output in its method getStrategyDecision()
. Of course, it can not be given a Strategy
because that class is abstract, so this argument has to be a reference. For my above reasons, it is not a pointer.
The following code does compile, but only because const
has been added in several places.
class Strategy {
public:
virtual int decision() const = 0;
};
class AlwaysZero : public Strategy {
public:
int decision() const { return 0; }
};
class Base {
private:
Strategy const &strategy;
public:
Base(Strategy const &s) : strategy(s) {}
int getStrategyDecision() {
return strategy.decision();
}
};
class Main : public Base {
public:
Main() : Base(AlwaysZero()) {}
};
int main ()
{
Main invoker;
return invoker.getStrategyDecision();
}
If you remove the const
qualifiers, it fails because in the constructor of Main
, passing the temporary object AlwaysZero()
to the reference argument of the constructor of Base
is illegal.
I could understand that error, but
- Why does it work when everything is
const
? This seems to suggest it should work withoutconst
equally well and I am just missing something. - I do not even want a "temporary" object, the only reason I have to do this is because I cannot pass a
Strategy
itself, because the class is abstract.
Again, I know I could solve this by making the variable strategy
a pointer to a Strategy
and passing a new AlwaysZero()
to the Base
constructor. This is what I do not want, as explained above.
My question is twofold. First, I want to know why my example compiles, when it does not without const
. I want to understand what is going on here.
Secondly, I would like to know if this example can be modified so that strategy
is no longer const
(and it works), but without using any kind of pointer. Only if the answer to this second question is "no", I will start looking for clever ways to avoid the problem (such as smart pointers, as suggested in the comments).
PS: I use g++ as a compiler. It might or might not matter.