Reputation: 26943
suppose this construct
struct InterfaceForFoo
{
virtual void GetItDone() = 0;
};
class APoliticallyCorrectImplementationOfFooRelatedThings : private InterfaceForFoo
{
public:
void GetItDone() { /*do the thing already*/ };
};
Now, i'm wondering if inheriting privately from an interface in this way do have any useful scenarios.
Upvotes: 4
Views: 973
Reputation: 208323
The question is why should it matter that the base class has only pure virtual methods?
The two things are almost unrelated. Private means that it is an implementation detail of your class, and not part of the public interface, but you might want to implement an interface as an implementation detail. Consider that you write a class, and that you decide to implement the functionality by means of a library that requires you to implement an interface. That is an implementation detail, there is no need to make the inheritance public just because the interface has only pure virtual functions.
Upvotes: 2
Reputation: 213308
Huh, everyone here says "no". I say "yes, it does make sense."
class VirtualBase {
public:
virtual void vmethod() = 0;
// If "global" is an instance of Concrete, then you can still access
// VirtualBase's public members, even though they're private members for Concrete
static VirtualBase *global;
};
// This can also access all of VirtualBase's 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);
}
};
Making inheritance private
doesn't mean that you can't access the members of VirtualBase
from outside the class, it only means that you can't access those members through a reference to Concrete
. However, Concrete
and its friends can cast instances of Concrete
to VirtualBase
, and then anybody can access public members. Simply,
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
Upvotes: 6
Reputation: 7061
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 would inherit privately from an interface, I don't know; that kind of defeats the purpose of interfaces.
If it's not an interface, but instead a class, it makes sense:
class A {
virtual void foo() = 0;
void bar() {
foo();
}
};
class B : private A {
virtual void foo() {
}
};
Upvotes: -1
Reputation: 69988
On object oriented aspect there is no use case for such private
inheritance for an abstract class
.
However, if you want to mandate that you child class
must derive certain methods then you can use this. For example:
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()
};
So, it just helps to maintain the personal coding discipline. Message with this example is that, inheritance is not just meant for object oriented purpose. You can even use inheritance for stopping inheritance chain (something like Java final).
Upvotes: 1
Reputation: 131789
Eh? No, that makes absolutely no sense, since the reason you provide an interface is that you want other to use your class through that interface. How would that work if they don't know you implement 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 doesn't work because the outside world doesn't know that DoesFoo
is a Fooable
, as such you cannot new
an instance of it and assign it to a Fooable*
.
Upvotes: -1