When designing an interface, someone recommended to use the non-virtual interface pattern. Can someone briefly outline what the benefits of this pattern are?
The essence of the non-virtual interface pattern is that you have private virtual functions, which are called by public non-virtual functions (the non-virtual interface).
The advantage of this is that the base class has more control over its behaviour than it would if derived classes were able to override any part of its interface. In other words, the base class (the interface) can provide more guarantees about the functionality it provides.
As a simple example, consider the good old animal class with a couple of typical derived classes:
class Animal { public: virtual void speak() const = 0; }; class Dog : public Animal { public: void speak() const { std::cout << "Woof!" << std::endl; } }; class Cat : public Animal { public: void speak() const { std::cout << "Meow!" << std::endl; } };
This uses the usual public virtual interface that we're used to, but it has a couple of problems:
std::cout << ... << std::endl;
boilerplate code.speak()
does. A derived class may forget the new line, or write it to cerr
or anything for that matter.To fix this, you can use a non-virtual interface that is supplemented by a private virtual function that allows polymorphic behaviour:
class Animal { public: void speak() const { std::cout << getSound() << std::endl; } private: virtual std::string getSound() const = 0; }; class Dog : public Animal { private: std::string getSound() const { return "Woof!"; } }; class Cat : public Animal { private: std::string getSound() const { return "Meow!"; } };
Now the base class can guarantee that it will write out to std::cout
and end with a new line. It also makes maintenance easier as derived classes don't need to repeat that code.
Herb Sutter wrote a good article on non-virtual interfaces that I would recommend checking out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With