inheritance & polymorphism (aka “object-oriented programming”)

26
• Inheritance Initialization & Destruction of Derived Objects Protected Members Non-public Inheritance Virtual Function Implementation Virtual Destructors Abstract Base Classes and Interfaces Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Upload: bian

Post on 12-Jan-2016

52 views

Category:

Documents


3 download

DESCRIPTION

Inheritance & Polymorphism (aka “Object-Oriented Programming”). Inheritance Initialization & Destruction of Derived Objects Protected Members Non-public Inheritance Virtual Function Implementation Virtual Destructors Abstract Base Classes and Interfaces. Inheritance. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

• Inheritance

• Initialization & Destruction of Derived Objects

• Protected Members

• Non-public Inheritance

• Virtual Function Implementation

• Virtual Destructors

• Abstract Base Classes and Interfaces

Inheritance & Polymorphism(aka “Object-Oriented Programming”)

Page 2: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Inheritance

• (Public) inheritance implements an “is-a” relationship– access of inherited members doesn’t change– private members of a base class are not

accessible in derived class methods– public inheritance is the default for struct

• Think “substitutability”– a derived object should be able to “stand-in” via a

base pointer– code sharing is just a side effect

• Don’t inherit just for code sharing

Page 3: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

• The base class constructor(s) run(s) first– in declaration order, if multiple inheritance– you pass arguments to base class constructors only

through the member initializer list– if the base class has a default constructor, no

explicit initializer is necessary

• Then any member objects are initialized– in declaration order

• Then the derived class constructor runs• Destruction is the reverse of this process

Object InitializationThe Real Story

Page 4: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

#include <iostream>using namespace std;

struct A { A() {cout << "A::A()\n";} ~A() {cout << "A::~A()\n";}};

struct B { B() {cout << "B::B()\n";} ~B() {cout << "B::~B()\n";}};

struct C : A { C() {cout << "C::C()\n";} ~C() {cout << "C::~C()\n";} B b;};

int main() { C c;}

A::A()B::B()C::C()C::~C()B::~B()A::~A()

Page 5: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

// Using Initializers#include <iostream>using namespace std;

struct A{ A(int i) {cout << "A::A(" << i << ")\n";} ~A() {cout << "A::~A()\n";}};

struct B{ B(int j) {cout << "B::B(" << j << ")\n";} ~B() {cout << "B::~B()\n";}};

struct C : A{ C(int i, int j) : A(i), b(j) { cout << "C::C(" << i << ',' << j << ")\n"; } ~C() {cout << "C::~C()\n";} B b;};

int main(){ C c(1,2);}

Page 6: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

A::A(1)B::B(2)C::C(1,2)C::~C()B::~B()A::~A()

Page 7: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

• There is a third access specifier - protected– protected members are accessible through

derived objects

• Idiom: Protected Constructors– Used to make a class abstract– An alternative to using pure virtual functions

Protected Members

Page 8: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Non-public Inheritance“Secretly” using an implementation

• Protected Inheritance– Public members in base sub-objects objects are

“downgraded” to protected in derived objects– The base class interface is only exposed to derived

classes

• Private Inheritance– Public and protected members in base sub-objects

objects are “downgraded” to private in derived objects– Known as pure “Implementation Inheritance”

• the interface of the base class is not exposed at all

– Similar to composition, without explicit forwarding

Page 9: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Name Hiding “Gotcha”

• Beware when “overriding” functions in derived classes

• Example: Hide.cpp

Page 10: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Name Lookup Rules

• 1. Find a scope for the name– A class constitutes a scope– A derived class scope is “nested” in the base class’s

scope

• 2. Perform overload resolution in that scope– Pick unambiguous “best fit”

• 3. Check access permission• Examples: Lookup1-3.cpp

Page 11: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

A Lookup Oddity?

• Why does the following compile?

#include <iostream>#include <string>

int main(){ std::string s = "hello"; std::cout << s; // Calls std::operator<<(ostream&, const string&); // but I didn’t import or specify it.}

Page 12: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Argument-dependent Lookup (ADL)

• States that when looking for a function, it will search the namespace of the parameter(s) as well

• Since s is in std, it looks in std for operator<<(ostream&, const string&);

• A convenience– “Implicit import”, if you will

• Causes weird problems with templates!

Page 13: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

The Goal of OOP

• To treat all objects as base objects• via a pointer-to-base

• But to have their behavior vary automatically• depending on the dynamic type of the object

EmployeeSalariedEmployee

etc.etc.

EmployeeSalariedEmployee

Page 14: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Heterogeneous Collections

int main(){ using namespace std; Employee e("John Hourly",16.50); e.recordTime(52.0); SalariedEmployee e2("Jane Salaried",1125.00); e2.recordTime(1.0); Employee* elist[] = {&e, &e2}; int nemp = sizeof elist / sizeof elist[0]; for (int i = 0; i < nemp; ++i) cout << elist[i]->getName() << " gets " << elist[i]->computePay() << endl;}

John Hourly gets 957Jane Salaried gets 1125

Page 15: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Function Binding

• Determines the code that executes for a functions call

• Static binding occurs at compile time– what we’re used to

• Dynamic binding occurs at run time– what Java and SmallTalk folks are used to– what we want here– determined by the dynamic type of object pointed to

Page 16: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

How Virtual Functions Work

vptrnameratetimeWorked

Employee

Employee::computePay()

vtbl for Employee

vptrsalaryGrade

SalariedEmployee

SalariedEmployee::computePay::

vtbl for SalariedEmployee

•Each class has a vtbl (pointers to its virtual functions)•Each object has a vptr (points to its class’s vtbl)

Page 17: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Advantages of Dynamic Binding

• Client code can just deal with the base type (e.g., Employee*)

• Behavior varies transparently according to an object’s dynamic type

• Client code remains unchanged when new derived types are created!

• No “ripple effect” for maintainers

Page 18: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Derived Destructors

• Recall that base class destructors are called automatically when a derived object dies:

struct B{ ~B() {std::cout << "~B\n";}};

struct D : B // public by default{ ~D() {std::cout << "~D\n";}};

int main(){ D d;}

~D~B

Page 19: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Deleting via a Pointer-to-Base

int main(){ B* pb = new D; delete pb;}

~B // Oops! Derived part not destoyed!

Page 20: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Virtual Destructors

• Needed when deleting via a pointer-to-base

struct B{ virtual ~B() {std::cout << "~B\n";}};

int main(){ B* pb = new D; delete pb;}

~D // Fixed!~B

Page 21: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

• Destructors can be declared virtual– necessary when a base class pointer or reference refers

to a derived class object– if the destructor is not declared virtual, only the base

class destructor is called– this may cause a memory leak

• Rule: Base classes should always have a virtual destructor

• Rule of Thumb: A class that contains a virtual function should also declare a virtual destructor

Virtual Destructors

Page 22: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Abstract Classes

• Sometimes a base class is just a conceptual entity– a category, or umbrella for related classes– you won’t instantiate any objects of that type

Vehicle

Car Truck Bus

Page 23: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Pure Virtual Functions

• Abstract classes usually have abstract methods:– “Place holder” member functions to be

overridden in derived classes– Don’t need an implementation in the base class

• The presence of such a pure virtual function makes its class abstract

• Append “= 0” to the function’s declaration

Page 24: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Explicit Interfaces

• A grouping of method specifications– Used in COM, CORBA, Java, .NET, good OO design

• Specified with only pure virtual functions in C++• To implement an interface, simply inherit and

provide all member function definitions• The client programs to the interface

– You can change the implementation transparent to the client

• Example: Strategy Design Pattern

Page 25: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

Implicit Interfaces

• A set of expected operations– a.k.a. “Duck Typing”

• If they’re there, things just work• If not, compile error• Example: STL Sequences

– Expected interface:• copy constructor• assignment operator• equality operator

• Example: STL Container Adaptors

Page 26: Inheritance & Polymorphism (aka “Object-Oriented Programming”)

RTTI

• Runtime Type Identification

• The typeid operator– Returns a type_info object– Include <typeinfo>

• Not useful for much– Type name

• For built-in and polymorphic types only