In C++, let's say I have a class Derived
that implements an interface class BaseInterface
, where BaseInterface
has only pure virtual functions and a virtual destructor:
class BaseInterface
{
public:
virtual void doSomething() = 0;
~BaseInterface(){}
};
class Derived : public BaseInterface
{
public:
Derived() {}
~Derived(){}
protected:
virtual void doSomething();
private:
int x;
};
No classes outside the Derived
class hierarchy should call Derived::doSomething()
directly, i.e., it should only be accessed polymorphically through the BaseInterface
class. To enforce this rule, I have made Derived::doSomething()
protected. This works well, but I'm looking for opinions pro/con regarding this approach.
Thanks!
Ken
I think you're looking for the non-virtual interface (NVI) pattern: a public
non-virtual interface that calls a protected or private virtual
implementation:
class BaseInterface
{
public:
virtual ~BaseInterface(){}
void doSomething() { doSomethingImpl(); }
protected:
virtual void doSomethingImpl() = 0;
};
class Derived : public BaseInterface
{
public:
Derived() {}
virtual ~Derived(){}
protected:
virtual void doSomethingImpl();
private:
int x;
};
If it is part of the interface, why would you not want users to call it? Note that as it is, they can call it: static_cast<BaseInterface&>(o).doSomething()
is just an awkward way of saying o.doSomething()
. What is the point of using the interface... if the object fulfills the interface, then you should be able to use it, or am I missing something?
Since you are not actually blocking anyone from calling the methods, I don't see a point in making the code more complex (both the class and users of the class) for no particular reason. Note that this is completely different from the Non-Virtual Interface in that in this idiom virtual functions are not accessible publicly (at any level) while in your case, the intention is allowing access, and making it cumbersome.
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