Why does the Boost Parameter choose inheritance rather than composition?

I believe that the majority of people on this site will agree that the implementation can be outsourced in two ways:

  • personal inheritance
  • Structure

Inheritance is most often abused. It is noteworthy that public inheritance is often used when another form or inheritance may be better, and in general, composition should be used, rather than private inheritance.

Of course, the usual caveats apply, but I can't think that I really need inheritance for the implementation problem.

For the Boost Parameter library, however, you will notice that they have chosen inheritance over the composition to implement the named idiom parameter (for the constructor).

I can only think of the classic explanation of EBO (Empty Base Optimization), since there are no virtual methods that I can see.

Does anyone know better or can redirect me to a discussion?

Thanks, Mathieu.

+4
source share
2 answers

EDIT : Oh! I posted the answer below because I didn’t read your post correctly. I thought you said that the Boost library used composition over inheritance, and not vice versa. However, if this is useful to anyone ... (See EDIT2 for what, in my opinion, might be the answer to your question.)

I do not know a specific answer for the Boost parameter library. However, I can say that this is usually the best choice. The reason is that whenever you have the opportunity to realize relationships in more than one way, you should choose the weakest (low connection / high cohesion). Because inheritance is stronger than composition ...

Note that sometimes using private inhertiance can make it difficult to implement code-exclusive code. Take operator== , for example. Using composition, you can create a temporary one and complete the task with the fixation / rollback logic (provided that the object is correctly constructed). But if you use inheritance, you'll probably do something like Base::operator==(obj) inside the operator== derived class. If a call to Base::operator==(obj) calls, you risk your guarantees.

EDIT 2: Now, trying to answer what you really requested. I understood this from the link you provided. Since I do not know all the details of the library, please correct me if I am mistaken.

When you use composition to be “realized in terms of”, you need one level of indirection for delegation.

 struct AImpl { //Dummy code, just for the example. int get_int() const { return 10; } }; 

struct A { AImpl * impl_; int get_int() const { return impl->get_int(); } /* ... */ };

In the case of a constructor with parameter support, you need to create an implementation class, but you can still use the wrapper class in a transparent way. This means that in the example from the link you myclass , you would be desirable if you could manipulate myclass in the same way as you could manipulate myclass_impl . This can only be done through inheritance. (Note that in the example, inheritance is publicly available, since it is the default for struct.)

I assume myclass_impl should be a “real” class, with data, behavior, etc. Then, if you had a method like get_int() , and if you did not use inheritance, you would have to write the get_int() wrapper in myclass just like I did above.

+2
source

This is not the library I've ever used, so taking a look at the documentation you referenced is the only thing I base this answer on. Maybe I'm going to be wrong, but ...

They mention constructor delegation as the reason for using a common base class. You are right that composition can solve this particular problem. However, all this in one type will not work. They want to boil a few constructor signatures into one user-defined initialization function, and without delegating a constructor that requires a second data type. My suspicion is that most of the library has already been written in terms of putting everything in the classroom. When they faced the problem of delegating the constructor, they compromised. Putting it in the base class was probably closer to what they were doing with the previous functionality, where they knew that the interfaces and aspects of the functionality implementation would be available for the class you are working with.

I do not slam the library in any way. I very much doubt that I can build such a library at any reasonable time. I just read between the lines. You know, speaking of ignorance, but pretending to really know something. :-)

0
source

All Articles