Private inheritance and composition, which is better and why?

suppose i have an engin class and i inherit a cool class from engin class

class engin { public: engin(int nobofcylinders); void start(); }; class car:private engin { public: car():e(8){} void start() { e.start(); } private: engin e; }; 

now the same thing can be done by composition, the question is which approach would be better and is mainly used in programming, and why ???????

+4
source share
8 answers

I prefer to think of inheritance as derived is a kind of base , which basically means public inheritance. In the case of private inheritance, it is more like derived has a base , that IMHO does not sound right, because IMHO is a work for composition, not inheritance of any kind. So, since private inheritance and composition essentially mean the same thing logically, what to choose? For the example that you published, I would probably go for the composition. What for? I tend to think of all kinds of inheritance as a kind of relationship, and with the example you published, I cannot think of a situation where I could say a car is kind of an engine , it just isn't. It really is like a car has an engine , so why is a car inherited from an engine? I see no reason.

Now there really are cases when it is good to have private inheritance, namely boost::noncopyable , while the ctor / dtor protection will be protected, it will be difficult for you to instantiate, and indeed, since we want our class to have a noncopyable part , which is the only way to go.

Some style guides (like the google C ++ style guide ) even recommend never using personal inheritance for reasons similar to what I already wrote - private inheritance is just a little confusing.

Hope this helps.

+4
source

The composition should be preferred for two main reasons:

  • the component of the item (s) may have names
  • you can make more than one type of the same type
+6
source

If you want to compare personal inheritance with composition, read http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.3 . I don’t think that private inheritance is good.


A Car has-a Engine , but a Car is-not-an Engine , so it's best to do it with a composition.

Inheritance is useful for is-a relationships, for example. a Bus is-a Car , a Car is-a vehicle , etc.

Composition is useful for has-a relationships, for example. a Car has Wheel -s, a Car has-a Engine , etc.

Thus, the logical code should look like

 class Car : public Vehicle { Engine engine; Wheel wheels[4]; ... }; 
+5
source

Private inheritance, despite the name, really is not inheritance - at least not from the outside (of the class) where it matters.

For this reason, different rules apply. In C ++, it is believed that private inheritance models "implemented in terms of" relationships. Thus, the priority queue, which is implemented as a heap, may look like this:

 template <typename T, typename Comp = std::less<T> > class priority_queue : private heap<T, Comp> { // … }; 

Personally, I do not see the advantages of this template, and Neil has already stated that in most cases the composition actually has an advantage over private inheritance.

However, there is one advantage: starting with such an established template, the value of private inheritance immediately becomes clear to an experienced C ++ programmer; the code above would tell them that the priority queue is implemented in terms of heap - which would not be obvious if the class simply used the heap as one of its members.

Private inheritance is typically used in C ++ mainly for policy classes. A classic example is allocators, which determine how a container class manages storage inside:

 template <typename T, typename A = std::allocator<T> > class vector : private A { // … }; 

No harm done. But once again this could be done using the composition.

+3
source

Usually the composition should be preferred (others gave the main reasons), but private inheritance allows things that cannot be performed by composition:

  • Optimization of a base class of zero size (a base class of zero size will not increase the size of the class, a member of size zero will be), this is the reason for its use for policy classes that often have no data

  • controls the order of initialization, so that what is composed is initialized in front of the public base

  • redefinition of the virtual member in what is composed

  • with private virtual inheritance, ensuring that there is only one thing folded, even if it does it in multiple databases

Note that for the next two uses, the fact that the base class exists can be observed with the descendant.

+3
source

Composition is used more than private inheritance. The general rule that I adhere to and recommend is that unless you have a specific reason to use personal inheritance, you should use composition.

A composition has many advantages over private inheritance:

  • You can have multiple instances of a particular class.
  • You do not pollute the namespace of your class with a bunch of private functions that do not make sense for your class.
  • You can name parts of your object
  • Your class is less associated with the classes it consists of than with the class that it inherits from
  • If you find that you need to change the object that you included in the composition during the life of your object, you can get stuck with private inheritance.

The composition has many other advantages. In principle, it is more flexible and cleaner.

There are reasons to use personal inheritance. These are very specific reasons, and if you think they apply, you should think carefully about your design to make sure you need to do this.

  • You can override virtual functions.
  • You can access protected members of the base class.
  • You need to pass yourself on to what the class object you inherit wants (usually this goes hand in hand with overriding virtual functions).

And there are some pretty complicated ones:

  • If you use composition for a class with size 0, it still takes a space, but with private inheritance it is not.
  • You want to call a specific constructor for the virtual base class of the class to which you will privately inherit.
  • If you want to initialize a private base before initializing other base classes (with composition, all variables in your class will be initialized after all base classes).
  • Use private virtual inheritance to make sure that there is only one copy of a thing, even if you have several base classes that it has. (In my opinion, this is best solved using pointers and normal composition.)
+3
source
  • Private inheritance means in-conditions. This is usually inferior to composition, but it makes sense when a derived class needs access to a protected base member class or needs to override inherited virtual functions.

  • Unlike composition, private inheritance can allow an empty optimization base. This can be important for library developers who want to minimize the size of objects.

Scott Myers "Effective C ++" Third Edition.

+1
source

Base classes are evil.

In my opinion, a good OO design is about encapsulation and interfaces. The convenience of base classes is not worth what you pay.

Here is a really good article about it:

http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html

-2
source

Source: https://habr.com/ru/post/1299233/


All Articles