When to use C++ private inheritance over composition? - c++

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.

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."

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.

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.

Related

Defining interfaces (abstract classes without members) in C++

By an interface (C# terminology) I mean an abstract class with no data members. Thus, such a class only specifies a contract (a set of methods) that sub-classes must implement. My question is: How to implement such a class correctly in modern C++?
The C++ core guidelines [1] encourage the use of abstract class with no data members as interfaces [I.25 and C.121]. Interfaces should normally be composed entirely of public pure virtual functions and a default/empty virtual destructor [from C.121]. Hence I guess it should be declared with the struct keyword, since it only contains public members anyway.
To enable use and deletion of sub-class objects via pointers to the abstract class, the abstract class needs a public default virtual destructor [C.127]. "A polymorphic class should suppress copying" [C.67] by deleting the copy operations (copy assignment operator, copy constructor) to prevent slicing. I assume that this also extends to the move constructor and the move assignment operator, since those can also be used for slicing. For actual cloning, the abstract class may define a virtual clone method. (It's not completely clear how this should be done. Via smart pointers or owner<T*> from the Guidelines Support Library. The method using owner<T> makes no sense to me, since the examples should not compile: the derived function still does not override anything!?).
In C.129, the example uses interfaces with virtual inheritance only. If I understand correctly, it makes no difference if interfaces are derived (perhaps better: "implemented"?) using class Impl : public Interface {...}; or class Impl : public virtual Interface {...};, since they have no data that could be duplicated. The diamond problem (and related problems) don't exist for interfaces (which, I think, is the reason why languages such as C# don't allow/need multiple inheritance for classes). Is the virtual inheritance here done just for clarity? Is it good practice?
In summary, it seems that:
An interface should consist only of public methods. It should declare a public defaulted virtual destructor. It should explicitly delete copy assignment, copy construction, move assignment and move construction. It may define a polymorphic clone method. I should be derived using public virtual.
One more thing that confuses me:
An apparent contradiction: "An abstract class typically doesn't need a constructor" [C.126]. However, if one implements the rule of five by deleting all copy operations (following [C.67]), the class no longer has a default constructor. Hence sub-classes can never be instantiated (since sub-class constructors call base-class constructors) and thus the abstract base-class always needs to declare a default constructor?! Am I misunderstanding something?
Below is an example. Do you agree with this way to define and use an abstract class without members (interface)?
// C++17
/// An interface describing a source of random bits.
// The type `BitVector` could be something like std::vector<bool>.
#include <memory>
struct RandomSource { // `struct` is used for interfaces throughout core guidelines (e.g. C.122)
virtual BitVector get_random_bits(std::size_t num_bits) = 0; // interface is just one method
// rule of 5 (or 6?):
RandomSource() = default; // needed to instantiate sub-classes !?
virtual ~RandomSource() = default; // Needed to delete polymorphic objects (C.127)
// Copy operations deleted to avoid slicing. (C.67)
RandomSource(const RandomSource &) = delete;
RandomSource &operator=(const RandomSource &) = delete;
RandomSource(RandomSource &&) = delete;
RandomSource &operator=(RandomSource &&) = delete;
// To implement copying, would need to implement a virtual clone method:
// Either return a smart pointer to base class in all cases:
virtual std::unique_ptr<RandomSource> clone() = 0;
// or use `owner`, an alias for raw pointer from the Guidelines Support Library (GSL):
// virtual owner<RandomSource*> clone() = 0;
// Since GSL is not in the standard library, I wouldn't use it right now.
};
// Example use (class implementing the interface)
class PRNG : public virtual RandomSource { // virtual inheritance just for clarity?
// ...
BitVector get_random_bits(std::size_t num_bits) override;
// may the subclass ever define copy operations? I guess no.
// implemented clone method:
// owner<PRNG*> clone() override; // for the alternative owner method...
// Problem: multiple identical methods if several interfaces are inherited,
// each of which requires a `clone` method?
//Maybe the std. library should provide an interface
// (e.g. `Clonable`) to unify this requirement?
std::unique_ptr<RandomSource> clone() override;
//
// ... private data members, more methods, etc...
};
[1]: https://github.com/isocpp/CppCoreGuidelines, commit 2c95a33fefae87c2222f7ce49923e7841faca482
You ask a lot of questions, but I'll give it a shot.
By an interface (C# terminology) I mean an abstract class with no data members.
Nothing specifically like a C# interface exists. A C++ abstract base class comes the closest, but there are differences (for example, you will need to define a body for the virtual destructor).
Thus, such a class only specifies a contract (a set of methods) that sub-classes must implement. My question is: How to implement such a class correctly in modern C++?
As a virtual base class.
Example:
class OutputSink
{
public:
~OutputSink() = 0;
// contract:
virtual void put(std::vector<std::byte> const& bytes) = 0;
};
OutputSink::~OutputSink() = default;
Hence I guess it should be declared with the struct keyword, since it only contains public members anyway.
There are multiple conventions for when to use a structure versus a class. The guideline I recommend (hey, you asked for opinions :D) is to use structures when you have no invariants on their data. For a base class, please use the class keyword.
"A polymorphic class should suppress copying"
Mostly true. I have written code where the client code didn't perform copies of the inherited classes, and the code worked just fine (without prohibiting them). The base classes didn't forbid it explicitly, but that was code I was writing in my own hobby project. When working in a team, it is good practice to specifically restrict copying.
As a rule, don't bother with cloning, until you find an actual use case for it in your code. Then, implement cloning with the following signature (example for my class above):
virtual std::unique_ptr<OutputSink> OutputSink::clone() = 0;
If this doesn't work for some reason, use another signature (return a shared_ptr for example). owner<T> is a useful abstraction, but that should be used only in corner cases (when you have a code base that imposes on you the use of raw pointers).
An interface should consist only of public methods. It should declare [...]. It should [...]. It should be derived using public virtual.
Don't try to represent the perfect C# interface in C++. C++ is more flexible than that, and rarely will you need to add a 1-to-1 implementation of a C# concept in C++.
For example, in base classes in C++ I sometimes add public non-virtual function implementations, with virtual implementations:
class OutputSink
{
public:
void put(const ObjWithHeaderAndData& o) // non-virtual
{
put(o.header());
put(o.data());
}
protected:
virtual void put(ObjectHeader const& h) = 0; // specialize in implementations
virtual void put(ObjectData const& d) = 0; // specialize in implementations
};
thus the abstract base-class always needs to declare a default constructor?! Am I misunderstanding something?
Define the rule of 5 as needed. If code doesn't compile because you are missing a default constructor, then add a default constructor (use the guidelines only when they make sense).
Edit: (addressing comment)
as soon as you declare a virtual destructor, you have to declare some constructor for the class to be usable in any way
Not necessarily. It is better (but actually "better" depends on what you agree with your team) to understand the defaults the compiler adds for you and only add construction code when it differs from that. For example, in modern C++ you can initialize members inline, often removing the need for a default constructor completely.
While the majority of the question has been answered, I thought I'd share some thoughts on the default constructor and the virtual inheritance.
The the class must always have a public (Or at least protected) constructor to assure that sub-classes can still call the super-constructor. Even though there is nothing to construct in the base class, this is a necessity of the syntax of C++ and conceptually makes no real difference.
I like Java as an example for interfaces and super-classes. People often wonder why Java separated abstract classes and interfaces into different syntactical types. As you probably already know though, this is due to the diamond inheritance problem, where two super-class both have the same base class and therefore copy data from the base class. Java makes this impossible be forcing data-carrying classes to be classes, not interfaces and forcing sub-classes to only inherit from one class (not interface which doesn't carry data).
We have following situation:
struct A {
int someData;
A(): someData(0) {}
};
struct B : public A {
virtual void modifyData() = 0;
};
struct C : public A {
virtual void alsoModifyData() = 0;
};
struct D : public B, public C {
virtual void modifyData() { someData += 10; }
virtual void alsoModifyData() { someData -= 10; }
};
When modifyData and alsoModifyData are called on an instance of D, they will not modify the same variable as one might expect due to the compiler which will create two copies of someData for classes B and C.
To counter this problem, the concept of virtual inheritance was introduced. This means that the compiler will not just brute-force recursively build up a derived class from the super-classes members but instead see if the virtual super-classes derive from a common ancestor. Very similarly, Java has the concept of an interface, which is not allowed to own data, just functions.
But interfaces can strictly inherit from other interfaces, excluding the diamond problem to begin with. This is where Java of course differs from C++. These C++ "Interfaces" are still allowed to inherit from data-owning classes, whereas this is impossible in java.
The idea of having a "virtual inheritance", which signals that the class should be sub-classed and that data from ancestors is to be merged in case of diamond inheritance makes the necessity (or at least the idiom) of using virtual inheritance on "Interfaces" clear.
I hope this answer was (although more conceptual) helpful to you!

Is it alright to put data members in an interface?

Recently, I've learnt about composite pattern. I want to use it in my assignment which I have to implement File and Folder classes. I realize that sub-classes like CFile and Cfolder got to have the same attributes (name and size). So is it alright for me to put the attributes into the interface? As far as I know, it is not good practice to do so. However, I don't understand why I shouldn't. Or is there any other solutions?
I would say its not a problem. Th difference is that instead of a pure interface class you have an abstract base class. However, if you want to retain the flexibility to use the interface for implementations that are not tied down to those specific member variables then you can always create an interface class as well as an abstract base class for full flexibility. Though that may be getting overly complex overly soon, you can always split the interface from the abstract base later if you need to.
using CItemUPtr = std::unique_ptr<class CItem>;
/**
* Interface class
*/
class CItem
{
public:
virtual ~CItem() {}
virtual CItemUPtr findByName(std::string const& name) = 0;
virtual void setHidden(bool a, bool b) = 0;
};
/**
* Abstract base class
*/
class AbstractCItem
: public CItem
{
protected:
std::string name;
std::size_t size;
};
class CFile
: public AbstractCItem
{
public:
CItemUPtr findByName(std::string const& name) override
{
// stuff
return {};
}
void setHidden(bool a, bool b) override {}
};
It's not really a question of "is it a good practice". By creating an interface, you're defining a standard. The question is, do you NEED the implementation of the interface to contain those data members? You are in the best position to understand your implementation, so you're really the only one who can answer this.
As a general rule, the class implementing the interface should be a black box, and the outside world shouldn't have access to any internals (including member data). Interfaces define common functionality that is required to be present to be able to support the interface, and I'd expect those implementation details to be buried in the underlying implementation of the class only, as a general rule. YMMV.
The design principle for a class should be:
'It is impossible to break the class invariant from the outside'
If the constructor(s) set up the class invariant, and all members
uphold the class invariant, this is achieved.
However, if the class does not have a class invariant, having
public members achieves the same thing.
// in C++, this is a perfectly fine, first order class
struct Pos
{
int x,y;
Pos& operator+=(const Pos&);
};
also see https://en.wikipedia.org/wiki/Class_invariant

Is it bad programming practice to mix virtual and non-virtual functions in a base class?

I have a base class Base that I declare several polymorphic subclasses of. Some of the base class's functions are pure virtual while others are used directly by the subclass.
(This is all in C++)
So for instance:
class Base
{
protected:
float my_float;
public:
virtual void Function() = 0;
void SetFloat(float value){ my_float = value}
}
class subclass : public Base
{
void Function(){ std::cout<<"Hello, world!"<<std::endl; }
}
class subclass2 : public Base
{
void Function(){ std::cout<<"Hello, mars!"<<std::endl; }
}
So as you can see, the subclasses would rely on the base class for the function that sets "my_float", but would be polymorphic with regards to the other function.
So I'm wondering if this is good practice. If you have an abstract base class, should you make it completely abstract or is it okay to do this sort of hybrid approach?
This is a common practice. In fact, some well-known design patterns rely on this, such as the Template Method Pattern. In a nutshell, this allows you to specify some aspects of the behavior you're describing through your class hierarchy as invariant, while letting other aspects of that behavior vary based on the specific type of instance you are referring to at a given point.
Whether or not it is a good or not depends on your precise use case: does it make sense for you to share the implementation of your float member data storage among all your base classes ? This is a bit hard to answer with the example you posted as the derived classes do not rely on my_float in any way, but there are tons of cases where this makes sense and is a good way to split the responsibilities of your class hierarchy.
Even in cases where it does make sense to share implementation of details across classes, you have several other options, such as using composition to share functionality. Sharing functionality through a base class often allows you to be less verbose compared to sharing this functionality via composition, because it allows you to share both the implementation and the interface. To illustrate, your solution has less duplicated code than this alternative that uses composition:
class DataStorage {
private:
float data_;
public:
DataStorage()
: data_(0.f) {
}
void setFloat(float data) {
data_ = data;
}
};
class NotASubclass1 {
private:
DataStorage data_;
public:
void SetFloat(float value){ data_.setFloat(value); }
...
}
class NotASubclass2 {
private:
DataStorage data_;
public:
void SetFloat(float value){ data_.setFloat(value); }
...
}
Being able to have some functions non-virtual has certain benefits, many strongly related:
you can modify them, knowing invocations via a Base*/Base& will use your modified code regardless of what actual derived type the Base* points to
for example, you can collect performance measurements for all Base*/&s, regardless of their derivation
the Non-Virtual Interface (NVI) approach aims for "best of both worlds" - non-virtual functions call non-public virtual functions, giving you a single place to intercept calls via a Base*/& in Base as well as customisability
calls to the non-virtual functions will likely be faster - if inline, up to around an order of magnitude faster for trivial functions like get/set for few-byte fields
you can ensure invariants for all objects derived from Base, selectively encapsulating some private data and the functions that affect it (the final keyword introduced in C++11 lets you do this further down the hierarchy)
having data/functionality "finalised" in the Base class aids understanding and reasoning about class behaviour, and the factoring makes for more concise code overall, but necessarily at the cost of frustrating flexibility and unforeseen reuse - tune to taste

C++ object without subclasses?

I was wondering if there is a way to declare an object in c++ to prevent it from being subclassed. Is there an equivalent to declaring a final object in Java?
From C++ FAQ, section on inheritance
This is known as making the class
"final" or "a leaf." There are three
ways to do it: an easy technical
approach, an even easier non-technical
approach, and a slightly trickier
technical approach.
The (easy) technical approach is to
make the class's constructors private
and to use the Named Constructor Idiom
to create the objects. No one can
create objects of a derived class
since the base class's constructor
will be inaccessible. The "named
constructors" themselves could return
by pointer if you want your objects
allocated by new or they could return
by value if you want the objects
created on the stack.
The (even easier) non-technical
approach is to put a big fat ugly
comment next to the class definition.
The comment could say, for example, //
We'll fire you if you inherit from
this class or even just /*final*/
class Whatever {...};. Some
programmers balk at this because it is
enforced by people rather than by
technology, but don't knock it on face
value: it is quite effective in
practice.
A slightly trickier technical approach
is to exploit virtual inheritance.
Since the most derived class's ctor
needs to directly call the virtual
base class's ctor, the following
guarantees that no concrete class can
inherit from class Fred:
class Fred;
class FredBase {
private:
friend class Fred;
FredBase() { }
};
class Fred : private virtual FredBase {
public:
...
};
Class Fred can access FredBase's ctor,
since Fred is a friend of FredBase,
but no class derived from Fred can
access FredBase's ctor, and therefore
no one can create a concrete class
derived from Fred.
If you are in extremely
space-constrained environments (such
as an embedded system or a handheld
with limited memory, etc.), you should
be aware that the above technique
might add a word of memory to
sizeof(Fred). That's because most
compilers implement virtual
inheritance by adding a pointer in
objects of the derived class. This is
compiler specific; your mileage may
vary.
No, there isn't really a need to. If your class doesn't have a virtual destructor it isn't safe to derive from it anyway. So don't give it one.
You can use this trick, copied from Stroustrup's FAQ:
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
In C++0x (and as an extension, in MSVC) you can actually make it pretty clean:
template <typename T>
class final
{
private:
friend T; // C++0x, MSVC extension
final() {}
final(const final&) {}
};
class no_derived :
public virtual final<no_derived> // ah, reusable
{};
NO.
The closest you can come is to declare the constructors private, then provide a static factory method.
There is no direct equivalent language construct for this in C++.
The usual idiom to achieve this technically is to declare its constructor(s) private. To instantiate such a class, you need to define a public static factory method then.
As of C++11, you can add the final keyword to your class, eg
class CBase final
{
...
The main reason I can see for wanting to do this (and the reason I came looking for this question) is to mark a class as non subclassable so you can safely use a non-virtual destructor and avoid a vtable altogether.
There is no way really. The best you can do is make all your member functions non-virtual and all your member variables private so there is no advantage to be had from subclassing the class.

When should I use C++ private inheritance?

Unlike protected inheritance, C++ private inheritance found its way into mainstream C++ development. However, I still haven't found a good use for it.
When do you guys use it?
I use it all the time. A few examples off the top of my head:
When I want to expose some but not all of a base class's interface. Public inheritance would be a lie, as Liskov substitutability is broken, whereas composition would mean writing a bunch of forwarding functions.
When I want to derive from a concrete class without a virtual destructor. Public inheritance would invite clients to delete through a pointer-to-base, invoking undefined behaviour.
A typical example is deriving privately from an STL container:
class MyVector : private vector<int>
{
public:
// Using declarations expose the few functions my clients need
// without a load of forwarding functions.
using vector<int>::push_back;
// etc...
};
When implementing the Adapter Pattern, inheriting privately from the Adapted class saves having to forward to an enclosed instance.
To implement a private interface. This comes up often with the Observer Pattern. Typically my Observer class, MyClass say, subscribes itself with some Subject. Then, only MyClass needs to do the MyClass -> Observer conversion. The rest of the system doesn't need to know about it, so private inheritance is indicated.
Note after answer acceptance: This is NOT a complete answer. Read other answers like here (conceptually) and here (both theoretic and practic) if you are interested in the question. This is just a fancy trick that can be achieved with private inheritance. While it is fancy it is not the answer to the question.
Besides the basic usage of just private inheritance shown in the C++ FAQ (linked in other's comments) you can use a combination of private and virtual inheritance to seal a class (in .NET terminology) or to make a class final (in Java terminology). This is not a common use, but anyway I found it interesting:
class ClassSealer {
private:
friend class Sealed;
ClassSealer() {}
};
class Sealed : private virtual ClassSealer
{
// ...
};
class FailsToDerive : public Sealed
{
// Cannot be instantiated
};
Sealed can be instantiated. It derives from ClassSealer and can call the private constructor directly as it is a friend.
FailsToDerive won't compile as it must call the ClassSealer constructor directly (virtual inheritance requirement), but it cannot as it is private in the Sealed class and in this case FailsToDerive is not a friend of ClassSealer.
EDIT
It was mentioned in the comments that this could not be made generic at the time using CRTP. The C++11 standard removes that limitation by providing a different syntax to befriend template arguments:
template <typename T>
class Seal {
friend T; // not: friend class T!!!
Seal() {}
};
class Sealed : private virtual Seal<Sealed> // ...
Of course this is all moot, since C++11 provides a final contextual keyword for exactly this purpose:
class Sealed final // ...
The canonical usage of private inheritance is the "implemented in terms of" relationship (thanks to Scott Meyers' 'Effective C++' for this wording). In other words, the external interface of the inheriting class has no (visible) relationship to the inherited class, but it uses it internally to implement its functionality.
One useful use of private inheritence is when you have a class that implements an interface, that is then registered with some other object. You make that interface private so that the class itself has to register and only the specific object that its registered with can use those functions.
For example:
class FooInterface
{
public:
virtual void DoSomething() = 0;
};
class FooUser
{
public:
bool RegisterFooInterface(FooInterface* aInterface);
};
class FooImplementer : private FooInterface
{
public:
explicit FooImplementer(FooUser& aUser)
{
aUser.RegisterFooInterface(this);
}
private:
virtual void DoSomething() { ... }
};
Therefore the FooUser class can call the private methods of FooImplementer through the FooInterface interface, while other external classes cannot. This is a great pattern for handling specific callbacks that are defined as interfaces.
I think the critical section from the C++ FAQ Lite is:
A legitimate, long-term use for private inheritance is when you want to build a class Fred that uses code in a class Wilma, and the code from class Wilma needs to invoke member functions from your new class, Fred. In this case, Fred calls non-virtuals in Wilma, and Wilma calls (usually pure virtuals) in itself, which are overridden by Fred. This would be much harder to do with composition.
If in doubt, you should prefer composition over private inheritance.
I find it useful for interfaces (viz. abstract classes) that I'm inheriting where I don't want other code to touch the interface (only the inheriting class).
[edited in an example]
Take the example linked to above. Saying that
[...] class Wilma needs to invoke member functions from your new class, Fred.
is to say that Wilma is requiring Fred to be able to invoke certain member functions, or, rather it is saying that Wilma is an interface. Hence, as mentioned in the example
private inheritance isn't evil; it's just more expensive to maintain, since it increases the probability that someone will change something that will break your code.
comments on the desired effect of programmers needing to meet our interface requirements, or breaking the code. And, since fredCallsWilma() is protected only friends and derived classes can touch it i.e. an inherited interface (abstract class) that only the inheriting class can touch (and friends).
[edited in another example]
This page briefly discusses private interfaces (from yet another angle).
Sometimes I find it useful to use private inheritance when I want to expose a smaller interface (e.g. a collection) in the interface of another, where the collection implementation requires access to the state of the exposing class, in a similar manner to inner classes in Java.
class BigClass;
struct SomeCollection
{
iterator begin();
iterator end();
};
class BigClass : private SomeCollection
{
friend struct SomeCollection;
SomeCollection &GetThings() { return *this; }
};
Then if SomeCollection needs to access BigClass, it can static_cast<BigClass *>(this). No need to have an extra data member taking up space.
Private Inheritance to be used when relation is not "is a", But New class can be "implemented in term of existing class" or new class "work like" existing class.
example from "C++ coding standards by Andrei Alexandrescu, Herb Sutter" :-
Consider that two classes Square and Rectangle each have virtual functions for setting their height and width. Then Square cannot correctly inherit from Rectangle, because code that uses a modifiable Rectangle will assume that SetWidth does not change the height (whether Rectangle explicitly documents that contract or not), whereas Square::SetWidth cannot preserve that contract and its own squareness invariant at the same time. But Rectangle cannot correctly inherit from Square either, if clients of Square assume for example that a Square's area is its width squared, or if they rely on some other property that doesn't hold for Rectangles.
A square "is-a" rectangle (mathematically) but a Square is not a Rectangle (behaviorally). Consequently, instead of "is-a," we prefer to say "works-like-a" (or, if you prefer, "usable-as-a") to make the description less prone to misunderstanding.
I found a nice application for private inheritance, although it has a limited usage.
Problem to solve
Suppose you are given the following C API:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
/* raw owning pointer, it's C after all */
char const * name;
/* more variables that need resources
* ...
*/
} Widget;
Widget const * loadWidget();
void freeWidget(Widget const * widget);
#ifdef __cplusplus
} // end of extern "C"
#endif
Now your job is to implement this API using C++.
C-ish approach
Of course we could choose a C-ish implementation style like so:
Widget const * loadWidget()
{
auto result = std::make_unique<Widget>();
result->name = strdup("The Widget name");
// More similar assignments here
return result.release();
}
void freeWidget(Widget const * const widget)
{
free(result->name);
// More similar manual freeing of resources
delete widget;
}
But there are several disadvantages:
Manual resource (e.g. memory) management
It is easy to set up the struct wrong
It is easy to forget freeing the resources when freeing the struct
It is C-ish
C++ Approach
We are allowed to use C++, so why not use its full powers?
Introducing automated resource management
The above problems are basically all tied to the manual resource management. The solution that comes to mind is to inherit from Widget and add a resource managing instance to the derived class WidgetImpl for each variable:
class WidgetImpl : public Widget
{
public:
// Added bonus, Widget's members get default initialized
WidgetImpl()
: Widget()
{}
void setName(std::string newName)
{
m_nameResource = std::move(newName);
name = m_nameResource.c_str();
}
// More similar setters to follow
private:
std::string m_nameResource;
};
This simplifies the implementation to the following:
Widget const * loadWidget()
{
auto result = std::make_unique<WidgetImpl>();
result->setName("The Widget name");
// More similar setters here
return result.release();
}
void freeWidget(Widget const * const widget)
{
// No virtual destructor in the base class, thus static_cast must be used
delete static_cast<WidgetImpl const *>(widget);
}
Like this we remedied all the above problems. But a client can still forget about the setters of WidgetImpl and assign to the Widget members directly.
Private inheritance enters the stage
To encapsulate the Widget members we use private inheritance. Sadly we now need two extra functions to cast between both classes:
class WidgetImpl : private Widget
{
public:
WidgetImpl()
: Widget()
{}
void setName(std::string newName)
{
m_nameResource = std::move(newName);
name = m_nameResource.c_str();
}
// More similar setters to follow
Widget const * toWidget() const
{
return static_cast<Widget const *>(this);
}
static void deleteWidget(Widget const * const widget)
{
delete static_cast<WidgetImpl const *>(widget);
}
private:
std::string m_nameResource;
};
This makes the following adaptions necessary:
Widget const * loadWidget()
{
auto widgetImpl = std::make_unique<WidgetImpl>();
widgetImpl->setName("The Widget name");
// More similar setters here
auto const result = widgetImpl->toWidget();
widgetImpl.release();
return result;
}
void freeWidget(Widget const * const widget)
{
WidgetImpl::deleteWidget(widget);
}
This solution solves all the problems. No manual memory management and Widget is nicely encapsulated so that WidgetImpl does not have any public data members anymore. It makes the implementation easy to use correctly and hard (impossible?) to use wrong.
The code snippets form a compiling example on Coliru.
If you need a std::ostream with some small changes (like in this question) you may need to
Create a class MyStreambuf which derives from std::streambuf and implement changes there
Create a class MyOStream which derives from std::ostream that also initializes and manages an instance of MyStreambuf and passes the pointer to that instance to the constructor of std::ostream
The first idea might be to add the MyStream instance as a data member to the MyOStream class:
class MyOStream : public std::ostream
{
public:
MyOStream()
: std::basic_ostream{ &m_buf }
, m_buf{}
{}
private:
MyStreambuf m_buf;
};
But base classes are constructed before any data members so you are passing a pointer to a not yet constructed std::streambuf instance to std::ostream which is undefined behavior.
The solution is proposed in Ben's answer to the aforementioned question, simply inherit from the stream buffer first, then from the stream and then initialize the stream with this:
class MyOStream : public MyStreamBuf, public std::ostream
{
public:
MyOStream()
: MyStreamBuf{}
, basic_ostream{ this }
{}
};
However the resulting class could also be used as a std::streambuf instance which is usually undesired. Switching to private inheritance solves this problem:
class MyOStream : private MyStreamBuf, public std::ostream
{
public:
MyOStream()
: MyStreamBuf{}
, basic_ostream{ this }
{}
};
If derived class
- needs to reuse code and
- you can't change base class and
- is protecting its methods using base's members under a lock.
then you should use private inheritance, otherwise you have danger of unlocked base methods exported via this derived class.
Sometimes it could be an alternative to aggregation, for example if you want aggregation but with changed behaviour of aggregable entity (overriding the virtual functions).
But you're right, it has not many examples from the real world.
A class holds an invariant. The invariant is established by the constructor. However, in many situations it's useful to have a view of the representation state of the object (which you can transmit over network or save to a file - DTO if you prefer). REST is best done in terms of an AggregateType. This is especially true if you're const correct. Consider:
struct QuadraticEquationState {
const double a;
const double b;
const double c;
// named ctors so aggregate construction is available,
// which is the default usage pattern
// add your favourite ctors - throwing, try, cps
static QuadraticEquationState read(std::istream& is);
static std::optional<QuadraticEquationState> try_read(std::istream& is);
template<typename Then, typename Else>
static std::common_type<
decltype(std::declval<Then>()(std::declval<QuadraticEquationState>()),
decltype(std::declval<Else>()())>::type // this is just then(qes) or els(qes)
if_read(std::istream& is, Then then, Else els);
};
// this works with QuadraticEquation as well by default
std::ostream& operator<<(std::ostream& os, const QuadraticEquationState& qes);
// no operator>> as we're const correct.
// we _might_ (not necessarily want) operator>> for optional<qes>
std::istream& operator>>(std::istream& is, std::optional<QuadraticEquationState>);
struct QuadraticEquationCache {
mutable std::optional<double> determinant_cache;
mutable std::optional<double> x1_cache;
mutable std::optional<double> x2_cache;
mutable std::optional<double> sum_of_x12_cache;
};
class QuadraticEquation : public QuadraticEquationState, // private if base is non-const
private QuadraticEquationCache {
public:
QuadraticEquation(QuadraticEquationState); // in general, might throw
QuadraticEquation(const double a, const double b, const double c);
QuadraticEquation(const std::string& str);
QuadraticEquation(const ExpressionTree& str); // might throw
}
At this point, you might just store collections of cache in containers and look it up on construction. Handy if there's some real processing. Note that cache is part of the QE: operations defined on the QE might mean the cache is partially reusable (e.g., c does not affect the sum); yet, when there's no cache, it's worth to look it up.
Private inheritance can almost always modelled by a member (storing reference to the base if needed). It's just not always worth it to model that way; sometimes inheritance is the most efficient representation.
Just because C++ has a feature, doesn't mean it's useful or that it should be used.
I'd say you shouldn't use it at all.
If you're using it anyway, well, you're basically violating encapsulation, and lowering cohesion. You're putting data in one class, and adding methods that manipulates the data in another one.
Like other C++ features, it can be used to achieve side effects such as sealing a class (as mentioned in dribeas' answer), but this doesn't make it a good feature.