When to use C++ private inheritance over composition?
Asked Answered
J

3

19

Can you give me a concrete example when is preferable to use private inheritance over composition? Personally, I will use composition over private inheritance, but there might be the case that using private inheritance is the best solution for a particular problem. Reading the C++ faq, gives you an example on using private inheritance, but I seems easier to use composition + strategy pattern or even public inheritance than private inheritance.

Jonniejonny answered 9/6, 2011 at 18:13 Comment(5)
There are a million dups for this question. Perform a search. And, as you state, you already found an example. Just because you didn't like it doesn't make it not an example...Vibrations
See: https://mcmap.net/q/540309/-copying-methods-from-memberVitrine
I think 'never' is the right answer...Kirovograd
Thanks, I did a search, but nothing showed up using the title strings, but I will rather use the template recursive pattern for this.Jonniejonny
See also #49502Luminiferous
D
8

private inheritance is typically used to represent "implemented-in-terms-of". The main use I have seen is for mixins using private multiple inheritance to build up a child object with the proper functionality from the various mixin parents. This can also be done with composition (which I slightly prefer) but the inheritance method DOES allow you to use using to expose some parent methods publicly, and allows for a slightly more convenient notation when using the mixin methods.

Dirk answered 9/6, 2011 at 18:21 Comment(1)
You nailed it! I can see why private inheritance might lead to an easier solution... thanks!Jonniejonny
M
18

Scott Meyers in "Effective C++" item 42 says

"Only inheritance gives access to protected members, and only inheritance allows for virtual functions to be redefined. Because virtual functions and protected members exist, private inheritance is sometimes the only practical way to express an is-implemented-in-terms-of relationship between classes."

Modie answered 9/6, 2011 at 18:20 Comment(0)
D
8

private inheritance is typically used to represent "implemented-in-terms-of". The main use I have seen is for mixins using private multiple inheritance to build up a child object with the proper functionality from the various mixin parents. This can also be done with composition (which I slightly prefer) but the inheritance method DOES allow you to use using to expose some parent methods publicly, and allows for a slightly more convenient notation when using the mixin methods.

Dirk answered 9/6, 2011 at 18:21 Comment(1)
You nailed it! I can see why private inheritance might lead to an easier solution... thanks!Jonniejonny
S
5

Privately inheriting interfaces

A typical application of private inheritance that many people overlook is the following.

class InterfaceForComponent
{
public:
    virtual ~InterfaceForComponent() {}
    virtual doSomething() = 0;
};

class Component
{
public:
    Component( InterfaceForComponent * bigOne ) : bigOne(bigOne) {}

    /* ... more functions ... */

private:
    InterfaceForComponent * bigOne;
};

class BigOne : private InterfaceForComponent
{
public:
    BigOne() : component(this) {}

    /* ... more functions ... */

private:
    // implementation of InterfaceForComponent
    virtual doSomething();

    Component component;
};

Usually BigOne would be a class with a lot of responsibilities. In order to modularize your code you would break your code into components, that help doing the little stuff. These components shouldn't be friends of BigOne, but still they might need some access to your class, that you don't want to give into the public, because it's implementation details. Hence you create an interface for that component to provide this restricted access. This makes your code better maintainable and to reason about, because things have clear boundaries of access.

I used that technique a lot in a several man-year project and it has paid off. Composition is not an alternative here.

Letting the compiler generate a partial copy-constructor and assignment

Sometimes, there are copyable/movable classes that have a lot of different data members. The compiler generated copy or move constructor and assignment would be fine, except for one or two data members that need special treatment. This can be annoying, if data members are added, removed or changed frequently, since hand-written copy and move constructors and assignments need to be updated each time. It produces code-bloat and make the class harder to maintain.

The solution is to encapsulate the data members, whose copy and move operations can be compiler-generated into an extra struct or class from which you privately inherit.

struct MyClassImpl
{
    int i;
    float f;
    double d;
    char c;
    std::string s;
    // lots of data members which can be copied/moved by the 
    // compiler-generated constructors and assignment operators. 
};

class MyClass : private MyClassImpl
{
public:
    MyClass( const MyClass & other ) : MyClassImpl( other )
    {
        initData()
    }

    MyClass( MyClass && other ) : MyClassImpl( std::move(other) )
    {
        initData()
    }

    // and so forth ...

private:
    int * pi;

    void initData()
    {
        pi = &p;
    }
};

You can then use the compiler-generated operations of the MyClassImpl class in the implementation of the respective operations of the class you are interested in. You could do the same with composition, but this would uglify your code in the rest of your class. If you used composition, the rest of the implementation would have to suffer because of this implementation detail of the copy and move operations. Private inheritance avoids this and avoids lots of code repetition.

Scriptural answered 15/8, 2012 at 17:9 Comment(5)
very interesting technique, though I am not sure i fully understand this, care to elaborate by adding a code that actually does something ? it would be really cool if you can provide an example that can run on cpp.sh to fully apreciate your codeCalderon
@BinaryA The trouble is, that it't hard to find a reasonable code example, because the code needs some complexity for the pattern to be reasonable. For me the use case was GUI code where I have a widget class that has tons of functionality. This functionality is encapsulated into sub components where each can talk back to the widget through a different interface. The widget class inherits privately from these interfaces and implements them.Scriptural
I just wanted to see how the call stack/sequence is performed, for example: what is the use of ~InterfaceForChild() ? why the ~ before it ?which class is initialized and called by the client ?Calderon
@BinaryA That's seemingly a typo, it's probably supposed to be ~InterfaceForComponent.Labialize
@Labialize Thanks for the hint. Fixed it.Scriptural

© 2022 - 2024 — McMap. All rights reserved.