Thursday, November 26, 2015

C++ : Private pure virtual method

class Engine
{
public:
    void SetState( int var, bool val );
    {   SetStateBool( int var, bool val ); }

    void SetState( int var, int val );
    {   SetStateInt( int var, int val ); }
private:
    virtual void SetStateBool(int var, bool val ) = 0;   
    virtual void SetStateInt(int var, int val ) = 0;   
};

Although they are private, private virtual functions can be overridden in the derived classes.
This
"allows for better separation of the specification of interface from the specification of the implementation's customizable behavior
(Herb Sutter).

Why ?


Imagine that the clas was written like this, with non-pure virtual methods :

 class Engine
{
private:
    virtual void SetState(bool val ) { // blablablabla };   
    virtual void SetState(int val )
{ // blablablabla };   
};
 and consider the following child class which overloads one method only:

 class MyEngine : public Engine
{
public:
    void SetState(int val )
{ // blablablabla };   
};

One would get in trouble by calling :

MyEngine* myEng = new MyEngine();
myEng->SetState(true);

This statement would  call SetState(int val), converting bool to int.
To have a proper inheritance, the child class shall use the using keyword to hide base class method:

class MyEngine : public Engine
{
          // To prevent SetState( int var, bool val ) from the base class,
          // from being hidden by the new implementation of the other overload

          // (below),
          // you have to put using declaration in the derived class

         using Engine::SetState;

public:
    void SetState(int val )
{ // blablablabla };   
};

This is something that the developer should always keep in mind and it can end to unexpected behaviors if not applied.
With private non-virtual, the developer could have written the first version of derived class without caring about non-hidden methods.

0 comments:

Post a Comment