html5-img
1 / 19

Multiple Inheritance in C++

CS 3370. Multiple Inheritance in C++. Multiple Base Classes. C++ allows multiple implementation inheritance Handy for multiple “is-a” situations Handy for reusing implementation without “is-a” Leads to C++’s Darkest Corner (IMHO) Inheritance “hierarchy” becomes a DAG Ambiguities galore!

remedy
Télécharger la présentation

Multiple Inheritance in C++

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CS 3370 Multiple Inheritance in C++

  2. Multiple Base Classes • C++ allows multiple implementation inheritance • Handy for multiple “is-a” situations • Handy for reusing implementation without “is-a” • Leads to C++’s Darkest Corner (IMHO) • Inheritance “hierarchy” becomes a DAG • Ambiguities galore! • Complicated rules

  3. Mixin Classes • Invented with Common Lisp (“Flavors”) • Clients inherit implementation to gain a capability • Printable, Storable, etc. • Mixin classes are often abstract • Provides most but not all of feature • You override virtual function(s) to complete the feature • A Mixin that itself happens to derive from another class should do so via virtual inheritance (described later) • See AbleTest.cpp

  4. Another MI ExampleInheriting Implementation “secretly” • Suppose we have the proverbial Shape hierarchy • Circle, Triangle, etc. • If there is common code to all shapes, you can put it in Shape • If it is common to only some, keep it a secret • Don’t have it derive from Shape • See next slide…

  5. Stroustrup Example class Shape {…}; class Common {…}; class Logo : public Shape {…}; class Circle : public Shape, protected Common {…}; class Triangle: public Shape, protected Common {…};

  6. MI Issues • A derived object has a subobject for each base class • data duplication! • Name clashes possible • Possible duplicate data via “diamond” inheritance • Examples: upcast.cpp, delta.cpp, ambiguous.cpp

  7. IOStreams Hierarchy Redux

  8. Virtual Inheritance • The derived class holds a pointer to the base subobject • It is not inherited by value • Only one subobject exists in the complete object • Therefore, there is no ambiguity in casting to the top-level class

  9. Ambiguous Names • There must be no ambiguity in name lookup • If multiple base classes contain the same member names, you have a problem • If a member function, you can override it and do the Right Thing • If a data member, you must use “::” • And they must still be accessible • Examples: ambiguous2.cpp, disambiguate.cpp

  10. Dominance • A fancy name for the way virtual functions work • The “most-derived” binding applies • B::fdominatesA::f if A is a (direct or indirect) base class of B • Non-virtual functions work the same way for consistency

  11. dominance.cpp What if a D object calls f( ) via a pointer?

  12. The Dark Corners • How do you initialize a virtual base? • With diamond inheritance, there are multiple paths to the shared base • Which intermediate class is responsible?

  13. Initializing Virtual Bases • None! • There’s no criterion for choosing • It is always initialized, therefore, by the most derived class • Other initializations are ignored, but must be supplied by every derived concrete class • This makes for weird, but necessary code • See next slides

  14. virtinit.cpp

  15. Order of InitializationThe Final Story (Really!) • All virtual bases are initialized before non-virtual bases • No matter where they are • In top-down-left-to-right order • Subobjects are never initialized twice • So the compiler has a lot of work to do to keep track of things

  16. virtinit2.cpp What is the order of initialization for G g; ? (See virtinit2.cpp)

  17. Inheritance and Copy Semantics • Affects copy constructors and assignment operators • Copy constructors work okay • Most-derived class must still take care of virtual base, similar to initialization example • Assignment operators are different! • They are not inherited • You must control all sub-assignments explicitly! • Examples: assignment.cpp, virtassign*.cpp

More Related