Over on StackOverflow, I was asked if I could come up with an example where private inheritance would be preferred to composition (in C++). The following is the situation I described, and I was wondering which implementation you would prefer. Most of the references I've found to private inheritance are poor uses, and I agree that it is rarely useful.
Let's say you have a class Foo
that should be immutable, but it's rather complicated to set up (maybe you're reading settings from a file), so you decide to create a separate class FooBuilder
to set up your Foo
objects for you. My solution (using private inheritance) is to declare an abstract interface:
class MutableFoo
{
public:
virtual void setValue(int n) = 0;
virtual void setSomethingElse(string s) = 0;
};
And my original Foo
class:
class Foo : private MutableFoo
{
public:
Foo(FooBuilder builder)
{
builder.build(this);
}
int value() const { return myValue; }
string somethingElse() const { return mySomethingElse; }
private:
void setValue(int n) { myValue = n; }
void setSomethingElse(string s) { mySomethingElse = s; }
int myValue;
string mySomethingElse;
};
And the FooBuilder
:
class FooBuilder
{
public:
FooBuilder(string fileWithSettings);
void build(MutableFoo *fooToBuild);
};
Now I can create read-only Foo
objects without declaring them all to be const
:
Foo aFoo(FooBuilder(aFileWithSettings));
A similar implementation using composition might look something like this:
class Foo
{
public:
Foo(FooData d);
int value() const { return data.value(); }
string somethingElse() const { return data.somethingElse(); }
private:
FooData data;
};
class FooData
{
public:
int value() const { return myValue; }
int somethingElse() const { return mySomethingElse; }
void setValue(int n) { myValue = n; }
void setSomethingElse(string s) { mySomethingElse = s; }
private:
int myValue;
string mySomethingElse;
};
class FooBuilder
{
public:
FooBuilder(string fileWithSettings);
FooData getData() const;
};
Foo aFoo(FooBuilder(aFileWithSettings).getData());
I don't see much difference between these implementations as far as coupling is concerned (which is the complaint I see most frequently leveled against inheritance vs. composition). In fact, the version using inheritance may have less coupling, as both Foo
and FooBuilder
depend on an abstract interface (MutableFoo
) instead of a concrete class FooData
. Also, if we have lots of methods, the composition version will end up with lots of simple delegations, which is tedious if nothing else.
Which do you prefer? Have I found a reasonable use for private inheritance? Have you found other reasonable uses?
And finally, has anyone ever found a legitimate use for protected inheritance? :-P