Multiple Inheritance Mechanics Compared to Flexible Construction Templates

This narrower version of the question is delayed due to being too wide.

On pages 6-7, Modern C ++ Design by Andrei Alexandrescu lists three ways in which multiple inheritance is weaker than templates with respect to building flexible designs. In particular, he claims that the mechanics provided by multiple inheritance are bad (the text in square brackets and formatting are mine according to my understanding of the context):

In such a setup [i.e. multiple inheritance], [to create flexible SmartPtr ] the user will create a multi-threaded class of smart pointers with reference counting, inheriting some BaseSmartPtr class and two classes: MultiThreaded and RefCounted . Any experienced cool designer knows that such a naive design does not work.

...

  • Mechanics. Missing template code for assembling legacy components in a controlled manner. The only tool that combines BaseSmartPtr, MultiThreaded, and RefCounted is a language engine called multiple inheritance. The language uses a simple superposition in a combination of base classes and establishes a set of simple rules for access to its members. This is unacceptable, except in the simplest cases. Most of the time, you need to organize the work of inherited classes in order to get the desired behavior.

Using multiple inheritance, you can achieve fairly flexible orchestration by writing member functions that call member functions of several base classes. So, what is orchestration that is absent in multiple inheritance and is present in templates?

Note that not all the drawbacks of multiple inheritance compared to templates come as an answer here, but only the drawback is what Andei calls mechanics in the above quote. In particular, make sure that you are not talking about one of the other two drawbacks of multiple inheritance listed by Andrew:

  1. Enter the information. Base classes do not have enough type information to continue their tasks. For example, imagine that you are trying to implement a deep copy for your smart pointer class, based on the base class of DeepCopy. But which interface do DeepCopy have? He must create objects of a type that he does not yet know.

  2. State management. The various behavioral aspects implemented with the base classes should be in the same state. This means that they must use virtual inheritance to inherit the base class that contains the state. This complicates the design and makes it more rigid, since the premise was that user classes inherit library classes, and not vice versa.

+4
c ++ multiple-inheritance templates
source share
1 answer

I think that what Alexandrescu talks about in the Mechanics section is outlined in the rest of the chapter. He refers to how much more flexible design based on policy is based on design of classes based on inheritance, especially in relation to different ways of implementing and combining policies - this is compared to a single implementation and combination allowed through multiple inheritance.

For example, when discussing Creator policies, he indicates that the policy requires only the Create () method, which returns a pointer to the class to be created, but does not indicate that it is virtual or non-static. And it shows several ways to create each policy: a simple policy class, such as (from section 1.5, skipping MallocCreator and PrototypeCreator policies)

 template<class T> struct OpNewCreator { static T* Create() { return new T; } }; 

...

 > //Library code > template <class CreationPolicy> > class WidgetManager:public CreationPolicy > { > ... > }; 

...

 // Application Code typedef WidgetManager<OpNewCreator<Widget> > MyWidgetMgr; 

or it can be implemented with template template parameters (section 1.5.1) as

 //Library Code template <template <class> class Creation Policy> class WidgetManager : public CreationPolicy <Widget> { ... } // Application Code typedef WidgetManager<OpNewCreator> MyWidgetMgr 

or (section 1.5.2) - implemented as a member function of the template:

 struct OpNewCreator { template <class T> static T* Create() { return new T; } 

}

These are examples of flexible mechanics that are available in a template-based policy class solution and are not available in a multiple inheritance solution. These specific examples may not be all that are interesting, perhaps because they should be short and simple for pedagogical reasons.

0
source share

All Articles