1 / 39

C++ Certificate Program C++ Intermediate

C++ Certificate Program C++ Intermediate. Inheritance in Depth. Topics. Multiple Inheritance Access Control Pointers to Members. Multiple Inheritance. class C : public A, public B { public : C(): A(), B() {} };. MI Overview.

meara
Download Presentation

C++ Certificate Program C++ Intermediate

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. C++ Certificate ProgramC++ Intermediate Inheritance in Depth

  2. Topics • Multiple Inheritance • Access Control • Pointers to Members

  3. Multiple Inheritance class C : public A, public B { public : C(): A(), B() {} };

  4. MI Overview • Mechanism that allows more than one direct base class (versus single inheritance) • Provides union of interfaces presented by the direct base classes

  5. MI Behavior • Virtual methods operate in the standard way • overloaded in the standard way • overridden in the standard way • Access control behaves in the same way • cannot use inheritance to circumvent access control • Polymorphism works in the standard way • C&/C* can be used where B&/B* or A&/A* occurs without loss of information

  6. MI Typical Uses • Most often a means of code reuse by pooling in multiple implementations • Review: protected methods and composition provide for code inheritance rather than interface inheritance • Used when required to exposed the interfaces of both direct base classes • Possible to override methods in the base classes

  7. Ambiguity Potential class A { public : A() {} virtual void foo(); virtual void bar(); }; class B { public : A() {} virtual void foo(); virtual void blah(); }; class C : public A, public B { public: C() : A(), B() {} };

  8. Ambiguity void func( A* a, B* b, C* c) { a->foo(); // ok, uses A::foo b->foo(); // ok, uses B::foo c->foo(): // ambiguous! which foo? }

  9. Resolving Ambiguities • Override explicitly (same name) in derived class class C : public A, public B { public: C() : A(), B() {} void foo() { A::foo();} };

  10. Resolving Ambiguities • Employ using-declaration class C : public A, public B { public: // … using A::foo; };

  11. Overloading Derived Methods with Using-Declaration • Need: compose a set of overloaded methods from base class(es) • Answer: Using-declaration .. this form of using-declaration must refer to methods in the base class(es) • Can not be used to make inaccessible information accessible

  12. Example class A { public : virtual void foo(int); }; class B { public : virtual void foo(std::string const &); virtual void blah(); }; class C : public A, public B { public: using A::foo; // un-hide A::foo using B::foo(); // un-hide A::foo void foo(double); // normally hides A::foo and B::foo };

  13. Replicated Base Classes • Multiple inheritance allows a class to be base more than once • By default, each base object is unique • Virtual base classes can combine common base objects (more detail ahead)

  14. Example class A { public: void foo(); void bar(); }; class B : public A { }; class C : public A { }; class D : public B, public C { public: D() : B(), C() {} void f(); };

  15. Explicit Referencing in Replicated Base Classes • Inside D, cannot refer to foo() and bar() methods from class A without risking ambiguity (which A base object are we using?) • Need to explicitly reference desired instance • Could also employ using-declaration

  16. Example void D::f() { foo(); // illegal – which foo? B::foo(); // ok, use B’s A::foo C::foo(); // ok, use C’s A::foo }

  17. Virtual Base Classes • Sometimes replicated instances are not appropriate • E.g. need a common state in the base • Usually due to implementation details (e.g. base constructor locks a shared resource) • Virtual base classes allow all derived classes to share single instance of a base (diamond inheritance graph)

  18. Virtual Base Example class A { }; class B : public virtual A { }; class C : public virtual A { }; class D : public B, public C { D() : B(), C() {} void f(); };

  19. Extending Base Behavior • Often want to override behavior in base classes • Replace (override) the functionality in a virtual method • Other times want to extend that behavior • Override base class virtual method, call the base class method, provide additional logic to extend functionality

  20. Example class B : public A { public: void open() ; // virtual method in A }; int B::open() { A::open(); // call base class version // add additional logic here }

  21. Why Use Multiple Inheritance? • Glue two otherwise unrelated implementation classes? • This is code inheritance • Not design-driven • Provide implementations for abstract base classes • ‘Mix-in’ classes • Compose new classes through multiple inheritance • Does not augment type so much as implementation • Deriving privately from std::list might be considered a "mix-in" by some

  22. Overriding Virtual Base Methods • Two different classes may override different virtual functions from the virtual base class • If two different classes override same virtual method from same virtual base class, ambiguity occurs - must resolve in same manner mentioned prior • One function must override all others

  23. Example class A { public: virtual void write() { } }; class B : public virtual A { public: void write(); // override A’s version }; class C : public virtual A { public: void write(); // override A’s version };

  24. Example // problem: which version of write() // gets called? class D : public B, public C { }; // this is OK, write() is overriding // versions in A, B, and C class D : public B, public C { public: void write() { } // overrides A, B, C // versions };

  25. Protected Members and Multiple Inheritance • Classes do not get access to sibling’s protected members • An object can access the protected members of another object of the same type • A class deriving from two siblings has access to protected members in both classes, even though the siblings do not

  26. Multiple Inheritance and Access Control • Any path or multiple paths may be used to access a base class or name • In the following rather contrived example, although A::foo() is not available from D via C, it is available from D via B. • Can use using-declaration to make a protected method part of public interface

  27. Example class A { protected: int foo(); }; class B : public virtual A { }; class C : private virtual A { }; // A::foo is visible via B, but // not via C

  28. Example class D : public B, public C { public: D() : B(), A() {} // A::foo() now becomes part of our // public interface using A::foo; };

  29. Using Declaration with Private Inheritance • Private or protected inheritance in conjunction with using-declaration can be used to ‘export’ a subset of an interface • In the following, B exports A::g() and B::x(), but none of A::h(), A::i() or B::y()

  30. Example class A { public : int g(); int h(); int i(); }; class B { public : int x(); int y(); };

  31. Example “Exporting” Methods class C : protected A, protected B { public : using A::g; using B::x; int func(); };

  32. Function Pointers • Taking a pointer to function • rt (*tag)(signature); • where rt is the return type, and signature is the argument list signature

  33. Taking Address of Function int foo(double d) { } int main() { // & optional in next line int (*pfoo)(double) = &foo; pfoo(2.0); // use like normal function }

  34. Pointers to Members • Pointers to members are similar, but slightly different • Require scope accessors • Cannot directly take address of member - are typically offsets into object (may need to consult v-table) • Can be used polymorphically • Static methods are same as regular functions

  35. Example Class A { public: int foo(double); int bar(double); }; // typedefs for this are common typedef int (A::*Fptrdef)(double); int f (A& a) { int (A::*fptr)(double) = a.foo; a->fptr(2); // must be called in context of an object, // hence the ‘a->’ fptr = a.bar; a->fptr(100.5); Fptrdef f = a.bar; a->f(5.1); }

  36. Late Binding • Virtual methods use ‘late-binding’ (runtime selection of appropriate derived method) • When a class has one or more virtual methods, a redirection mechanism is implemented • Typically, mechanism consists of virtual pointer, or v-ptr, and virtual table, or v-table • Object stores a v-ptr, typically at offset 0, that points to a v-table • V-table contains addresses (function pointers) for virtual methods of the class

  37. Example class A { public: virtual void foo() =0; virtual void bar(); }; class B : public A { public: void foo(); // use A::bar(); }; class C { public: void blah(); };

  38. V-Tables • V-table for A • foo() -> NULL • bar() -> A::bar() • V-table for B • foo() -> B::foo() • bar() ->A::bar() • Class C has no virtual methods, and hence has no v-table

  39. Selecting Virtual Methods • When a virtual method is invoked, compiler adds code to reference address of that method from v-table • Object is created from most-derived class, v-ptr constructed to point to proper v-table … if base pointer taken, v-ptr will cause proper method to be invoked • Works only with addresses, i.e., pointers and references, not objects • Slight overhead in virtual methods, “use ’em only when you need ‘em” • In case of A::foo() above, if class has one or more pure virtuals, cannot instantiate an instance of type (foo() has no address and will go boom)

More Related