Question

In my C++ application I have an interface that looks like this:

class ICalculator
   {
   public:
      virtual double calculateValue(double d) = 0;
   };

I have implementations of this interface that look like this:

class MySpecificCalculator
   {
   public:
      virtual double calculateValue(double d);
   };

Now my colleague complains about this and tells me it's better to have the calculateValue method protected. That way, we can guarantee that the callers always pass via the interface and not via the direct implementation.

Is this a correct observation? Is it really better to make the implementation of an interface protected? Or can't we even make it private then?

Was it helpful?

Solution

Your colleague is right.

Never make virtual functions public.

Guideline #1: Prefer to make interfaces nonvirtual, using Template Method.

Guideline #2: Prefer to make virtual functions private.

Guideline #3: Only if derived classes need to invoke the base implementation of a virtual function, make the virtual function protected.

For the special case of the destructor only:

Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual.

OTHER TIPS

It sounds that your colleague means:

class ICalculator
{
public:
    virtual double calculateValue(double d) const = 0;
};

class MySpecificCalculator : public ICalculator
{
protected:
    double calculateValue(double d) const;
};

void Calc(double d, const ICalculator& c)
{
    std::cout << "Result = " << c.calculateValue(d) << std::endl;
}

int main ()
{
    MySpecificCalculator c;
    c.calculateValue(2.1);  // dont do this
    Calc(2.1, c);  // do this instead
    return 0;
}

I cant see any benefit from this design. Why not to be able to call calculate from a concrete reference. To move calculateValue to protected in the derived class, breaks the contract of the base class. You can't use a MySpecificCalculator to calculate a Value, but its base class says so.

Btw this behaviour is not modeled by the NVI idiom explained by Chubsdad (which is the 'correct' way).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top