 Inheritance  Protected Members  Non-public Inheritance  Virtual Function Implementation  Virtual Destructors  Abstract Base Classes and Interfaces.

Slides:



Advertisements
Similar presentations
CPA: C++ Polymorphism Copyright © 2007 Mohamed Iqbal Pallipurath Overview of C++ Polymorphism Two main kinds of types in C++: native and user-defined –User-defined.
Advertisements

V IRTUAL F UNCTIONS Chapter 10 Department of CSE, BUET 1.
© Copyright Eliyahu Brutman Programming Techniques Course Version 1.0.
Rossella Lau Lecture 8, DCO10105, Semester B, DCO10105 Object-Oriented Programming and Design  Lecture 8: Polymorphism & C++ pointer  Inheritance.
Inheritance, Polymorphism, and Virtual Functions
Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.
Shallow Versus Deep Copy and Pointers Shallow copy: when two or more pointers of the same types point to the same memory – They point to the same data.
Lecture 6: Polymorphism - The fourth pillar of OOP - 1.
CSE 332: C++ Classes From Procedural to Object-oriented Programming Procedural programming –Functions have been the main focus so far Function parameters.
Computer Science and Software Engineering University of Wisconsin - Platteville 7. Inheritance and Polymorphism Yan Shi CS/SE 2630 Lecture Notes.
CSE 332: C++ Overloading Overview of C++ Overloading Overloading occurs when the same operator or function name is used with different signatures Both.
OOP Languages: Java vs C++
CSE 332: C++ Algorithms II From Last Time: Search with Generic Iterators Third generalization: separate iterator type parameter We arrive at the find algorithm.
Chapter 4 Inheritance Bernard Chen Spring Objective IS-A relationships and the allowable changes for derived classes The concept of polymorphism.
Chapter 12: Adding Functionality to Your Classes.
C++ Object Oriented 1. Class and Object The main purpose of C++ programming is to add object orientation to the C programming language and classes are.
CSE 425: Object-Oriented Programming II Implementation of OO Languages Efficient use of instructions and program storage –E.g., a C++ object is stored.
1 Classes- Inheritance Multiple Inheritance It is possible to derive a new class from more than one base class. This is called Multiple Inheritance. Under.
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Taken from slides of Starting Out with C++ Early Objects Seventh Edition.
Chapter 15 – Inheritance, Virtual Functions, and Polymorphism
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Slide
Polymorphism &Virtual Functions
Polymorphism &Virtual Functions 1. Polymorphism in C++ 2 types ▫Compile time polymorphism  Uses static or early binding  Example: Function and operator.
CSE 332: C++ templates This Week C++ Templates –Another form of polymorphism (interface based) –Let you plug different types into reusable code Assigned.
The Rest of the Story.  Constructors  Compiler-generated  The Initializer List  Copy Constructors  Single-arg (conversion ctors)  The Assignment.
1 Inheritance We are modeling the operation of a transportation company that uses trains and trucks to transfer goods. A suitable class hierarchy for the.
Programming Languages and Paradigms Object-Oriented Programming (Part II)
Algorithm Programming Bar-Ilan University תשס"ח by Moshe Fresko.
Object Oriented Programming with C++/ Session 6 / 1 of 44 Multiple Inheritance and Polymorphism Session 6.
Chapter 3 Inheritance and Polymorphism Goals: 1.Superclasses and subclasses 2.Inheritance Hierarchy 3.Polymorphism 4.Type Compatibility 5.Abstract Classes.
Polymorphism and Virtual Functions. Topics Polymorphism Virtual Functions Pure Virtual Functions Abstract Base Classes Virtual Destructors V-Tables Run.
Copyright 2006 Oxford Consulting, Ltd1 February Polymorphism Polymorphism Polymorphism is a major strength of an object centered paradigm Same.
CSCI-383 Object-Oriented Programming & Design Lecture 18.
CS-1030 Dr. Mark L. Hornick 1 Basic C++ State the difference between a function/class declaration and a function/class definition. Explain the purpose.
Copyright © 2008 Pearson Addison-Wesley. All rights reserved. Chapter 15 Inheritance.
Inheritance Initialization & Destruction of Derived Objects Protected Members Non-public Inheritance Virtual Function Implementation Virtual Destructors.
Overview of C++ Polymorphism
Object-Oriented Programming “The Rest of the Story”, CS 4450 – Chapter 16.
Recap Introduction to Inheritance Inheritance in C++ IS-A Relationship Polymorphism in Inheritance Classes in Inheritance Visibility Rules Constructor.
Inheritance ndex.html ndex.htmland “Java.
Object Oriented Programming Elhanan Borenstein Lecture #7.
Terms and Rules II Professor Evan Korth New York University (All rights reserved)
CS 342: C++ Overloading Copyright © 2004 Dept. of Computer Science and Engineering, Washington University Overview of C++ Overloading Overloading occurs.
Polymorphism & Virtual Functions 1. Objectives 2  Polymorphism in C++  Pointers to derived classes  Important point on inheritance  Introduction to.
 Virtual Function Concepts: Abstract Classes & Pure Virtual Functions, Virtual Base classes, Friend functions, Static Functions, Assignment & copy initialization,
CSE 332: C++ Overloading Overview of C++ Overloading Overloading occurs when the same operator or function name is used with different signatures Both.
A First Book of C++ Chapter 12 Extending Your Classes.
Design issues for Object-Oriented Languages
Inheritance Modern object-oriented (OO) programming languages provide 3 capabilities: encapsulation inheritance polymorphism which can improve the design,
CMSC 202 Polymorphism.
CS 3370 – C++ Object-oriented Programming
7. Inheritance and Polymorphism
Andy Wang Object Oriented Programming in C++ COP 3330
Polymorphism &Virtual Functions
Class A { public : Int x; A()
Object-Oriented Programming & Design Lecture 18 Martin van Bommel
Object-Oriented Programming
Polymorphism.
Inheritance and Run time Polymorphism
Inheritance & Polymorphism
Polymorphism & Virtual Functions
Polymorphism Lec
Virtual Functions Department of CSE, BUET Chapter 10.
Inheritance, Polymorphism, and Virtual Functions
Overview of C++ Overloading
Polymorphism Polymorphism
Polymorphism CMSC 202, Version 4/02.
Overview of C++ Polymorphism
C++ Object Oriented 1.
Lecture 6: Polymorphism
Presentation transcript:

 Inheritance  Protected Members  Non-public Inheritance  Virtual Function Implementation  Virtual Destructors  Abstract Base Classes and Interfaces

and Inheritance

#include 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()

// Using Initializers #include 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); }

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

 (1) The base class constructor(s) run(s) first  in declaration order with multiple inheritance  use the initializer list to pass data ▪ or default initialization occurs  (2) Then any member objects are initialized  in declaration order  (3) Then the derived class constructor runs  Destruction is the reverse of this process

 private class members are only accessible in member functions of the class  protected class members are also accessible through derived objects  however deeply derived  Base classes provide two interfaces:  one for universal access (the public interface)  one for derived clients (the protected interface)  See protected.cpp

 Allows derived classes to customize parts of an algorithm  The invariant parts stay in the base class  Derived classes override protected member functions  which are called from the algorithm skeleton in the base class

class Base : public IBase { void fixedop1() { cout << "fixedop1\n"; } void fixedop2() { cout << "fixedop2\n"; } public: void theAlgorithm() { fixedop1(); missingop1(); fixedop2(); missingop2(); } protected: virtual void missingop1() = 0; virtual void missingop2() = 0; };

class Derived : public Base { void missingop1() { cout << "missingop1\n"; } void missingop2() { cout << "missingop2\n"; } }; int main() { Derived d; d.theAlgorithm(); } /* Output: fixedop1 missingop1 fixedop2 missingop2 */

 Prevents public clients from instantiating an object  But derived class member functions can  So base objects exist only as a subobject in a derived object  A class that can’t be publicly instantiated is called an abstract class  How else can a class be made abstract?

 As soon as no references to an object exist, it self-destructs  Put the counting and self-destruction in an abstract base class  Let’s call it Counted  Then have the existing class to derive from Counted (see counted.cpp)  (Diagram on next slide)

 public  Most common  “is-a” relationship ▪ Derived class inherits both interface and implementation ▪ Derived objects can substitute for base objects ▪ via a pointer or a reference ▪ No change in access to inherited items via derived objects  protected  private

 Protected Inheritance  Private Inheritance

 public base members are “downgraded” to protected for clients of derived objects  The public base interface is not accessible to clients of derived objects

 public and protected base members are “downgraded” to private for clients of derived objects  Similar to composition, but without explicit forwarding  See stack-private-list.cpp

 A derived class using non-public inheritance can selectively “open-up” base members  The using declaration  Place in the protected or public section  Can’t give more accessibility than the original!  Opens up all overloaded members with that name  See publish.cpp, publish2.cpp

 Beware when “overriding” functions in derived classes  Only override virtual functions  Signatures must match exactly  Example: Hide.cpp

 1. Find a scope for the name  A class constitutes a scope  A derived class scope is considered “nested” in the base class’s scope  2. Perform overload resolution in that scope  Pick unambiguous “best fit”  3. Finally, check access permission  Examples: Lookup1-3.cpp

 Why does the following compile? #include int main() { std::string s = "hello"; std::cout << s; // Calls std::operator<<(ostream&, const string&); // but I didn’t import or specify it! }

 When looking for a function definition to match a function call, the namespaces (scopes) of the parameters are also searched  Since s is in std, it looks in std for operator<<(ostream&, const string&)  A convenience  “Implicit import”, if you will

 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 Employee SalariedEmployee etc. Employee SalariedEmployee

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

 Function binding dispatches (determines) the code to execute for a particular function call  Static binding occurs at compile time  Non-virtual functions are bound at compile-time  Dynamic binding occurs at run time  virtual functions are bound at runtime  must be called through a pointer or reference  determined by the dynamic type of the object pointed to

vptr name rate timeWorked Employee Employee::computePay() vtbl for Employee vptr salaryGrade 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)

 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

 Suppose B derives from A  Suppose f takes an A parameter by value: void f(A a) {…}  You can send a b to f: f(b);// B “is-a “A  But you have a problem…  an A object is created locally  only the A part is copied (the B part is discarded/sliced)  The object a has the vptr for class A!  Moral: Pass objects by reference! Sheesh!

 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

int main() { B* pb = new D; delete pb; } ~B// Oops! Derived part not cleaned up! Why?

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

 Destructors can be declared virtual  necessary when a base class pointer refers to a derived class object  if the destructor is not declared virtual, only the base class destructor is called  this may cause a resource 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

 Default arguments are resolved at compile time  This means that they follow the static type of the object that calls the function  the pointer type (usually a base class type)  no polymorphism involved to determine the default value  So it is usually best to provide a default value only in the (top) base class  See defaultargs.cpp

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

 Abstract classes usually have abstract methods:  A “place holder” function declaration meant to be overridden in derived classes  Don’t need an implementation in the base class (but can have in C++)  The presence of such a pure virtual function makes a class abstract  Append “= 0” to the function’s declaration  Example: vehicle.cpp

 A grouping of method specifications  No implementation at all  Specified with only pure virtual functions in C++  To implement an interface, simply derive and provide all member function bodies  The client codes to the interface  You can change the implementation without the client knowing  Example: Strategy Design Pattern

See queue.cpp

 The important part of public inheritance is the is-a relationship  interface sharing is more important (and more flexible) than code sharing  because programming to an interface is the keystone of good OO design  therefore…  In general, public base classes should be abstract classes

 A set of assumed operations  a.k.a. “Duck Typing”  If they’re there, things just work  If not, compile error  Example: STL Sequences (vector, list, deque)  Expected interface: ▪ copy constructor ▪ assignment operator ▪ equality operator  Example: STL Container Adaptors (see queue0.cpp)

 Runtime Type Identification  The typeid operator  Returns a type_info object  Include  Not useful for much  Reveals the type name  For built-in and polymorphic types only  Example: vehicle2.cpp

 A runtime cast  Used to “downcast” a base pointer  If the dynamic type is substitutable for (i.e., “is-a”) the requested type, a valid pointer is returned  Otherwise 0 (NULL) is returned  Rarely needed  Normally we just let polymorphism do the Right Thing  Example: vehicle3.cpp

 Most OOP languages support single dispatch  functions are dynamically bound by inspecting only one hierarchy  the most derived function that applies is dispatched  Example:  Suppose class D derives from C derives from B derives from A, and all but C define/override f( )  Which function is dispatched for p->f( ) if p is a base pointer (A*) that points to a C object?

 Single dispatch isn’t the only game in town  Why should the calling object be more important than the parameter(s)?  Consider x.f(y) vs. f(x,y)  the latter puts x and y on equal grounds  two hierarchies can be considered  this is called multiple dispatch  supported natively by Lisp  dynamic_cast can be used for this in C++…

VWX A ✔✔ B ✔ C ✔ Definitions for f(): What is the “most derived” function for the calls: x.f(c), c.f(x), c.f(w), w.f(c)? (See doubledisp.lsp)

 List parameter combinations most general to most specific:  A,V *  A,W  A,X *  B,V  B,W  B,X *  C,V *  C,W  C,X  Reverse, keeping only existing methods:  C,V  B,X  A,X  A,V  To dispatch, test parameters in the order above, left-to-right, using RTTI  See doubledisp.cpp

 V A *  V B  V C *  W A  W B  W C  X A *  X B *  X C  X B *  X A *  V C *  V A *  See doubledisp-B.cpp

 Any number of hierarchies/parameters may be used  Again, applicable methods are considered in “most derived” order

 See multimeth.cpp ZVWX A ✔✔ B ✔ C ✔ YVWX A ✔ B ✔ C ✔