Does it make sense to inherit confidentially from an abstract (pure virtual) class?

suppose this construction

struct InterfaceForFoo { virtual void GetItDone() = 0; }; class APoliticallyCorrectImplementationOfFooRelatedThings : private InterfaceForFoo { public: void GetItDone() { /*do the thing already*/ }; }; 

Now I am wondering if there is private inheritance from the interface in this way, there are some useful scenarios.

+4
source share
5 answers

Yes, everyone says no here. I say yes, it makes sense.

 class VirtualBase { public: virtual void vmethod() = 0; // If "global" is an instance of Concrete, then you can still access // VirtualBase public members, even though they're private members for Concrete static VirtualBase *global; }; // This can also access all of VirtualBase public members, // even if an instance of Concrete is passed in, void someComplicatedFunction(VirtualBase &obj, ...); class Concrete : private VirtualBase { private: virtual void vmethod(); public: void cmethod() { // This assignment can only be done by Concrete or friends of Concrete VirtualBase::global = this; // This can also only be done by Concrete and friends someComplicatedFunction(*this); } }; 

Creating private inheritance does not mean that you cannot access VirtualBase members from outside the class, it means that you cannot access these elements through the Concrete link. However, Concrete and his friends can transfer instances of Concrete to VirtualBase , and then anyone can access public members. Simply put,

 Concrete *obj = new Concrete; obj->vmethod(); // error, vmethod is private VirtualBase *obj = VirtualBase::global; obj->vmethod(); // OK, even if "obj" is really an instance of Concrete 
+5
source

Regarding the object-oriented aspect, there is no use for such private inheritance for an abstract class .

However, if you want to indicate that your child class should receive certain methods, you can use this. For instance:

 struct implement_size { virtual size_t size () = 0; }; class MyVector : private implement_size { public: size_t size () { ... } // mandatory to implement size() } class MyString : private implement_size { public: size_t size () { ... } // mandatory to implement size() }; 

Thus, it just helps maintain personal encoding . The message with this example is that inheritance is not just for an object-oriented purpose. You can even use inheritance to stop the inheritance chain (something like Java final).

+1
source

The question is, why does it matter that the base class has only pure virtual methods?

Two things are almost unconnected. The quotient means that this is an implementation detail of your class, and not part of the open interface, but you can implement the interface as an implementation detail. Think that you are writing a class, and that you decide to implement functionality using a library that requires an implementation of an interface. This is a detail of the implementation; there is no need to make inheritance publicly available only because the interface has only pure virtual functions.

+1
source

A? No, that makes no sense at all, because the reason you provide the interface is because you want the other to use your class through that interface. How will this work if they do not know that you are implementing it?

 #include <vector> class Fooable{ public: virtual void foo() = 0; }; class DoesFoo : private Fooable { void foo(); }; int main(){ std::vector<Fooable*> vf; vf.push_back(new DoesFoo()); // nope, doesn't work vf[0]->foo(); } 

The above example does not work because the outside world does not know that DoesFoo is Fooable , so you cannot new instance of it and assign it Fooable* .

0
source

Not really. If you need a function, you implement it. It makes no sense to force a function that cannot be used by other classes.

Why you inherited privately from the interface, I do not know; This type of hitting targets is interfaces.

If this is not an interface, but a class instead, this makes sense:

 class A { virtual void foo() = 0; void bar() { foo(); } }; class B : private A { virtual void foo() { } }; 
-1
source

All Articles