Date post: | 07-Aug-2015 |
Category: |
Engineering |
Upload: | sanya6900 |
View: | 72 times |
Download: | 1 times |
1
Topics on Inheritance
Subtyping and Code Reuse
Typing Conversions and Visibility
Abstract Base Classes
Multiple Inheritance
Inheritance and Design
Detailed C++ Considerations
3
The Inheritance Mechanism
Means of deriving new class from existing classes, called base classes
Reuses existing code eliminating tedious, error prone task of developing new code
Derived class developed from base by adding or altering code
Hierarchy of related types created that share code & interface
4
Single and Multiple Inheritance
Single inheritance occurs when single base class
Multiple inheritance occurs when more thanone base class
7
Taxonomic Classification (1 of 3)
Elephant and mouse both mammalsDescriptions succinct
Root concept "mammal" Warm-blooded
Higher vertebrates
Nourish young using milk-producing mammary glands
8
Taxonomic Classification (2 of 3)
Mammal
Warm blooded
Higher vertebrate
Nourish young with milk-producing glands
Mouse Elephant
9
Taxonomic Classification (3 of 3)
In C++ terms, classes elephant and mouse derived from base class "mammal"
In OOP terms, elephant ISA mammal describes relationship
If circus had elephants, then object circus might have members of type elephant
Class circus HASA elephant describes subpart relationship
10
Virtual Member Functions
Functions declared in base class and redefined in derived class
Class hierarchy defined by public inheritance creates related set of user types, all of whose objects may be pointed at by a base class pointer
By accessing virtual function through this pointer, C++ selects appropriate function definition at run-time
11
Pure Polymorphism
Object being pointed at must carry around type information so distinction can be made dynamically
Feature typical of OOP code
Each object "knows" how it is acted on
Inheritance designed into software to maximize reuse and allow natural modeling of problem domain
12
The OOP Design Methodology
1. Decide on an appropriate set of types
2. Design in their relatedness
3. Use inheritance to share code among classes
13
A Derived Class
Class derived from an existing classclass classname:(public|protected|private)opt
basename
{ member declarations};
Keyword class replaced by struct with members public by default
Keywords public, protected, and private used to specify how base class members are accessible to derived class
15
A Base Class: student
class student {public: enum year { fresh, soph, junior, senior, grad }; student(char* nm, int id, double g, year x); void print() const; protected: int student_id; double gpa; year y; char name[30];};
16
A Derived Class: grad_student
class grad_student : public student {public: enum support { ta, ra, fellowship, other }; grad_student(char* nm, int id, double g, year x, support t, char* d, char* th); void print() const;protected: support s; char dept[10]; char thesis[80];};
17
Inheriting from the Base Class
Derived class is modification of base class that inherits public and protected members of base class
In grad_student, student members are inherited
student_id gpa
name year
18
Add New Members in Derived Class
Derived class adds new members to existing class members
grad_student has three new data members and redefined member function
s
dept
thesis
print()
19
Benefits of Inheritance
Code is reusedgrad_student uses tested code from student
Reflects relationship in problem domainSpecial grouping grad student outgrowth
of real world and treatment of this group
Polymorphic mechanisms allow client code to treat inherited class as subtype of base class
Simplifies code, maintains subtype distinctions
20
Public Inheritance (is a subtype)
Publicly inherited remain public
Private members can't be inherited
Protected members remain protected
student
grad_student
shape
ellipse polygon
21
Private Inheritance (is not a subtype)
Public members become private
Protected members become private
Code reuse mechanism
generic tree
string tree
private
22
Typing Conversions and Visibility
Publicly derived class is subtype of base
Variable of derived class treated as if it were base class type
Pointer type pointer-to-base-class can point to objects of derived class type
Subtle implicit conversions occur between base and derived typeDifficult to follow what member is
accessed if base and derived class overloaded same member name
24
More on the student Program (1 of 7)
student::student(char* nm, int id, double g, year x) :student_id(id), gpa(g), y(x){ strcpy(name, nm);}
Constructor for base class does series of simple initializations
Calls strcpy() to copy student's name
25
More on the student Program (2 of 7)
//publicly derivedgrad_student::grad_student(char* nm, int id, double g, year x, support t, char* d, char* th) :student(nm, id, g, x), s(t){ strcpy(dept, d); strcpy(thesis, th); }
Constructor for student invoked as part of initializer list
Logically base class object needs to be constructed first before object can be completed
student_id and gpa are protected which makes them visible only to the derived class
26
More on the student Program (3 of 7)
Reference to derived class may be implicitly converted to a reference to public base class
grad_student gs("Morris Pohl", 200, 3.2564, grad, ta, "Pharmacy", "Retail Pharmacies");student& rs = gs; //aliasstudent* ps = &gs; //pointer init
Variable rs is reference to studentBase class of grad_student is student
Reference conversion is appropriate
27
More on the student Program (4 of 7)
void student::print(){ cout << name << " , " << student_id << " , " << y << " , " << gpa << endl;}void grad_student::print(){ student::print(); //base class info cout << dept << " , " << s << endl << thesis << endl;}
Infinite loop if not scope-resolved student::print()
28
More on the student Program (5 of 7)
#include "student.h" main() //Test pointer conversion rules{ student s("Mae Pohl", 100, 3.425, fresh), *ps = &s; grad_student gs("Morris Pohl",200, 3.2564, grad, ta, "Pharmacy", "Retail Pharmacies"), *pgs; ps —> print();//student::print ps = pgs = &gs; ps —> print();//student::print pgs —> print(); //grad_student::print}
29
More on the student Program (6 of 7)
main() declares both class variables and pointers to them
Conversion rule - pointer to publicly derived class may be converted implicitly to pointer to its base class
Pointer ps can point to objects of both classes, but pointer pgs can point only at objects of type grad_student
30
More on the student Program (7 of 7)
First ps -> print() invokes student::print
ps = pgs = &gs; both pointers pointing at object of type grad_student and assignment to ps involves implicit conversion
Second ps -> print(); invokes student::print Irrelevant that pointer points at grad_student
variable gs
pgs -> print(); invokes grad_student::print
pgs is of type pointer to grad_student and, when invoked with an object of this type, selects a member function from this class
31
Creating a New vect Class
“We can rewrite this safe-array code to include a new vect_bnd class with dynamic bounds checking. We’ll use vect as a base class, and let vect_bnd use inheritance so we don’t have to repeat all the vect code. It’s basic functions serve our purposes exactly.”
32
Dynamic Array Bounds (1 of 2)
Subscripting & assignment use these properties
Right side, lvalue automatically dereferenced
Left side specifies where value is stored
Safe array vect_bnd produced by deriving it from vect and invoking appropriate constructors
function-header : base-class-name (args)
33
Dynamic Array Bounds (2 of 2)
Safe array has constructors, destructor and overloaded subscripting operator
Constructors convert ordinary integer array to safe array by allocating sufficient memory
Upper and lower bounds checked
Subscript operator [] overloaded with function which tests for out-of-bounds condition on array access
34
Reuse code and extend vect type to safe array with dynamic bounds
More flexible and allows indices to correspond directly to problem domain
Example: Fahrenheit temperatures of water in its liquid state are is 32—212 degrees
Lower bound of 32 and upper bound of 212 Safe array vect checked array bounds for
in range and created arrays using free store
Using Dynamic Array Bounds
35
Dynamic Array Bounds (1 of 8)
class vect {public: //constructors & destructor vect(); //create a size 10 array vect(int l); //create a size l array vect(const vect& v); //init by vect vect(int a[], int l); //init by array ~vect() { delete [] p; } int ub() const {return (size—1);} int& operator[](int i); //range checked vect& operator=(vect& v); vect operator+(vect& v);private: int *p; //base pointer int size; //number of elements};
36
Dynamic Array Bounds (2 of 8)
class vect_bnd: public vect {public: vect_bnd(); vect_bnd(int, int); int& operator[](int); int ub() const { return (u_bnd); }//accessor int lb() const { return (l_bnd); }private: int l_bnd, u_bnd;};
Derived type members l_bnd and u_bnd privately store lower and upper bounds
37
Dynamic Array Bounds (3 of 8)
Derived type reuses base type's representation and code
Derived class constructors invoke base class constructors
Syntax is same as member initialization
function header: base—class—name(args)
38
u_bnd
l_bnd
Dynamic Array Bounds (4 of 8)
vect_bnd::vect_bnd() :vect(10){ l_bnd = 0; u_bnd = 9;}
vect_bnd::vect_bnd(int lb, int ub) : vect(ub — lb + 1){ l_bnd = lb; u_bnd = ub;}
Additional code initializes bound's pair
Derived constructors call base constructors
0 1 2 3 4 5 6 7 8 9
39
Dynamic Array Bounds (5 of 8)
Alternatively, could be done in initializing list
vect_bnd::vect_bnd(int lb, int ub) vect(ub — lb + 1), l_bnd(lb), u_bnd(ub) {}
40
Dynamic Array Bounds (6 of 8)
int& vect_bnd::operator[](int i){ if (i < l_bnd || u_bnd < i) { cerr << "index out of range" << endl; exit(1); } return (vect::operator[](i — l_bnd));}
Reuse code in overloading indexing operator []
Very inefficient - checking bounds twice
41
Dynamic Array Bounds (7 of 8)
To avoid inefficient double bounds check, make two changes
First change access privilege of vect::p to protected so derived class has direct access to previously private implementation of vect
Allows us to make second change of using p in vect_bnd::operator[]()
42
Dynamic Array Bounds (8 of 8)
int& vect_bnd::operator[](int i){ if (i < l_bnd || u_bnd < i) { cerr << "index out of range\n"; exit(1); }; return (p[i — l_bnd]);}
43
Determining Access Privilege
Tradeoff in code reuse and efficiency
Inheritance requires thinking about three access boundaries
What is to be strictly private and what is to be protected depends on what is reusable
44
Dynamic Virtual Function Selection
Typically base has virtual function and derived have their versions of function
Pointer to base class can point at either base or derived class objects
Member function selected depends on class of object being pointed at, not on pointer type
In absence of derived type member, base class virtual function used by default
45
Virtual & Overloaded Function Selection
Overloaded member function is compile-time selected based on signature
It can have distinct return types
Once declared virtual, this property is carried along to all redefinitions in derived classes
virtual modifier not needed in derived functions
46
Virtual Function Selection (1 of 2)
#include <iostream.h>
class B {public: int i; virtual void print_i() const { cout << i << " inside B" << endl; }};
class D: public B { //virtual toopublic: void print_i() const { cout << i << " inside D" << endl; }};
47
int main(){ B b; B* pb = &b; //point at a B object D f;
f.i = 1 + (b.i = 1); pb —> print_i(); //call B::print_i() pb = &f; //point at a D object pb —> print_i(); //call D::print_i()}
Virtual Function Selection (2 of 2)
1 inside B2 inside D
48
Comments on the virt Program
Different print_i() executedDynamically selected on object pointed
at
"Object sent message print_i and selects its corresponding version of method"
Pointer's base type is not determining method (function) selection
Different class objects processed by different functions at run-time
ADTs, inheritance, and process of objects dynamically are essentials of OOP
49
Confusion with Overloading (1 of 2)
Member function overloading and virtual functions cause mix-ups and confusion
class B {public: virtual foo(int); virtual foo(double); . . .};class D: public B {public: foo(int); . . .};
50
Confusion with Overloading (2 of 2)
main(){ D d; B b, *pb = &d; b.foo(9.5); //selects B::foo(double); d.foo(9.5); //selects D::foo(int); pb —> foo(9.5); //B::foo(double);}
Base class function B::foo(int) overriden in derived class
Base class function B::foo(double) hidden in derived class
51
Restrictions on virtual Functions
Only non-static member functions virtual
Virtual characteristic is inherited Derived class function
automatically virtual virtual keyword not needed
Constructors cannot be virtual
Destructors can be virtual
53
Using virtual (1 of 2)
class shape {public: virtual double area() const {return (0);} protected: double x, y;};
class rectangle: public shape {public: double area() const {return (height * width);}private: double height, width;};
54
Using virtual (2 of 2)
class circle: public shape {public: double area() const { return (PI * radius * radius); }private: double radius;};
55
Comments on the shapes Program
Virtual function allow run-time decisions
Different shapes derived from shape base class
Derived classes correspond to important, well understood types of shapes
Added to by deriving further classes
Area calculation is a local responsibility
56
Client Code for shapes
shape* p[N];. . .for (i = 0; i < N; ++i) tot_area += p[i] —> area();
Advantage that client code need not change if new shapes added
Change managed locally and propagated automatically by polymorphic character of client code
57
Classes and Virtual Functions
Root class of hierarchy usually contains number of virtual functions to provide dynamic typing
Pure virtual function provides dummy functions as placeholders in base class which had specific functions in derived classes
58 62
Pure Virtual Functions
Pure virtual function has body virtual function prototype = 0;
Pure virtual function used to defer implementation decision of the function
In OOP terminology - deferred method
59 63
Abstract Base Classes
Class with at least 1pure virtual function
Useful to have root class for type hierarchy as abstract class
Basic common properties of derived classes but cannot itself declare objects
Declare pointers that access subtype objects derived from abstract class
60
Using Abstract Base Classes (1 of 2)
Primitive form of ecological simulation in which world has different forms of life interacting
Abstract base class is livingInterface inherited by various forms
of life
Fox as archetypal predator and rabbit as its prey
Rabbit eats grass
62
Predator - Prey (1 of 5)
hierarchy livingconst int N = 40; //size of square boardenum state {EMPTY, GRASS, RABBIT, FOX, STATES} ;const int DRAB = 3, DFOX = 6, CYCLES = 5;
class living; //forward declarationtypedef living* world[N][N];
Akin to Conway's "Game of Life" simulation
Rules for who lives in next cycle given populations in neighborhood of square
63
Predator - Prey (2 of 5)
class living { //what lives in the worldpublic: virtual state who() = 0; //state id virtual living* next(world w) = 0;protected: int row, column; //location void sums(world w, int sm[]); };
Virtual functions incur small added run-time cost over normal member functions, use only when necessary
64
Predator - Prey (3 of 5)
//currently only plant life
class grass : public living {public: grass(int r, int c):{row=r; column=c;} state who() { return GRASS; } living* next(world w);};
Similar code developed for fox and rabbit
65
Predator - Prey (4 of 5)
//nothing lives hereclass empty : public living {public: empty(int r, int c): {row=r; column=c;} state who() { return EMPTY; } living* next(world w);};
Inheritance hierarchy one level deep
Design allows other forms of predator, prey, and plant life development using further level of inheritance
66
Predator - Prey (5 of 5)
living* grass::next(world w){ int sum[STATES]; sums(w, sum); if (sum[GRASS] > sum[RABBIT]) //eat grass return (new grass(row, column)); else return (new empty(row, column));}
If more grass than rabbits, grass remains; otherwise grass eaten
Rabbits die of old age or eaten by foxes foxes die of overcrowding and old age
67
Comment on the living Program
More interesting to simulate other behaviors such as sexual reproduction, where animals have gender and can mate
Array world is container for life formsHas responsibility for creating current
pattern
Needs to have ownership of living objects to allocate new ones and delete old ones
Rules in versions of next() determine possibly complex set of interactions
68
Multiple Inheritance
Derived class from more than one base
Can’t be circular, so no class may, through its inheritance chain, inherit from itself
Ambiguities arise when deriving identically named member from different classes
Virtual inheritance eliminated duplication of subobjects having same name
Constructor invoke order may cause problems, and should be explicit
70
Multiple Inheritance (1 of 3)
#include <iostream.h>
class tools {public: int cost() { return (1); }};class labor {public: int cost() {return (2); }};class parts {public: int cost() {return (3); }};
71
Multiple Inheritance (2 of 3)
class plans : public tools, public parts, public labor {public: int tot_cost() {return (parts::cost()+labor::cost());}};
Header has base classes, privacy designation
Publicly inherits members of all base classes
72
Multiple Inheritance (3 of 3)
main(){ int price; plans* ptr; tools t; labor l; parts p; plans pl; ptr = &pl; price = ptr -> cost(); //ambiguous cost price = ptr -> tools::cost(); cout << "\ntools cost = " << t.cost() << " labor cost = " << l.cost() << " parts cost = " << p.cost() << " plans cost = " << pl.tot_cost() << " total cost = " << price << endl;}
73
Virtual Inheritance
Two base classes derived from common ancestor
If both base classes used in ordinary way by derived class, that class will have two subobjects of common ancestor
Duplication, if not desirable, eliminated by using virtual inheritance
74
Using Virtual Inheritance (1 of 2)
class under_grad: public virtual student { . . .};
class grad: public virtual student {
. . .};
class attendee: public under_grad, public grad { . . .};
75
Without use of virtual, class attendee would have objects of class::under_grad::student and class::grad::student
Using Virtual Inheritance (2 of 2)
student
under_grad grad
attendee
76
Constructors and Destructors
With all these classes interacting, how do the constructors and destructors get invoked?
77
Constructor Destructor Execution (1 of 4)
Order for initializing constructors Base classes initialized in declaration order
Members initialized in declaration order
Virtual base classes have special precedence & are constructed before their derived classes
Constructed before non-virtual base classes
Construction order depends on their DAG
It is a depth-first, left-to-right orderDestructors invoked in reverse order of
constructors
78
Constructor Destructor Execution (2 of 4)
class tools {public: tools(char*); ~tools();};class parts {public: parts(char*); ~parts();};class labor { ...};
79
Constructor Destructor Execution (3 of 4)
class plans: public tools, public parts, public labor { special a; //class with constructorpublic: plans(int m): tools("lathe"), parts("widget"), labor(m), a(m) { . . . } ~plans(); . . .};
Old style list implicitly called base class constructor is allowed for SI - poor style
80
Constructor Destructor Execution (4 of 4)
Constructor initializing list and member initializing list in declaration order
Good style - avoids confusion and should match declaration order as documentation
Since its constructor was last, ~a() destructor is invoked first, followed by ~labor(), ~parts(), ~tools(), and ~plans()
Example of MI in iostream.h - derived from istream and ostream
81
Inheritance And Design
Inheritance is a code-sharing technique
Inheritance reflects understanding of problem
Inheritance reflects relationships between parts of problem space
82
The ISA Relationship
Public inheritance expression of ISA relationship between base and derived classes
Rectangle is shapeMake shape superclass
Allow behavior described by public member functions interpretable on objects within type hierarchySubclasses derived from it share
its interface
83
Design Tradeoffs
Design involves tradeoffs between objectives
Generality at odds with efficiency
Use class hierarchy for ISA relationships Compartmentalize coding
relationships
Coding inefficiencies having various layers of access to (hidden) state description
Simplifies overall coding process
85
Designing a Shape Drawing Package
Need not anticipate future additional shapes
Class developer imports base class "shape" interface and provides code that implements operations such as "draw"
What is primitive or common remains unchanged
Also unchanged is clients use of package
86
Concerns Affecting Class Development
Undue amount of decomposition imposes its own complexity
Self-defeating
Granularity decisionClasses highly specialized do not
provide enough benefit
Better folded into larger concept
87
Single vs.. Multiple Inheritance
Single Inheritance Multiple Inheritance
Credit Cards
Same basic features but each a little different
Voice Mail
Features of both mail phone
88
Deciding on Which Inheritance to Use
Generally types are best understood as SI chains
Some programmers prefer SI and aggregation to MI and composition
MI presents problems for type theoristA student might be derived from
person
An employee might be derived from personWhat about a student-employee?
89
What About Bats?
Is vampire bat mammal that flies, flying machine that is mammal, or flying machine and mammal?
Depending on what code is available, developing proper class for vampire bat might involve MI derivation or SI with appropriate HASA members
90
Subtyping Form
ADTs successful insofar as behave like native types
Native types such as integer types in C act as subtype hierarchy
Useful model for publicly derived type hierarchies
Promotes ease of use through polymorphism
91
Flexibility in Design (1 of 2)
class Abstract_Base {public://interface — largely virtual Abstract_Base(); //default constructor Abstract_Base(const Abstract_Base&); virtual ~Abstract_Base(); virtual void print() = 0; //usual print . . .protected://replaces private - inheritance . . .private: //empty — avoid: constrains future . . .};
92
Flexibility in Design (2 of 2)
class D_is_AB: virtual public Abstract_Base {public: //interface — supports concrete instance D_is_AB(); //default constructor D_is_AB(const D_is_AB&); //copy D_is_AB& operator=(const D_is_AB&); void print(); //usual print expectation . . .protected://replace private for inheritance . . .private: . . .};
93
Comments on the abs_base Program
Usual to leave root of hierarchy as abstract - yields most flexible design
Generally no concrete implementation developed at this point
Pure virtual functions preclude from declaring objects of this type
print() function is pure
94
Operations expected of any subtype in hierarchy
In general, basic constructors expected and they may not be virtual
Most useful aggregates require explicit definition of assignment that differs from default assignment semantics
First Design Level is Public (1 of 2)
95
First Design Level is Public (2 of 2)
Destructor virtual - response at run-time and dependent on object's size
Virtual public inheritance ensures that in MI schemes, no multiple copies of abstract base class
96
ISA sub-type "whale is mammal"
LIKEA code-reuse "bat is like airplane"
HASA sub-element "a plane has motor"
Chief confusion is multiple inheritance in place of HASA
Multiple Inheritance Relationships
97
C++ and Virtual Functions
Virtual function and derived instances having same signature must have same return type
Virtual function redefinition is overriding
Non-virtual member functions having same signature can have different return types
All member functions except constructors, and overloaded new and delete can be virtual
98
C++ and Constructors and Destructors
Constructors, destructors, and conversion functions do not have return types
Return type of an overloaded new operator must be void*
Return type of an overloaded delete operator must be void
Constructors, destructors, overloaded operator=, and friends not inherited
99
Operator Overloading
= , () , [] , and —> done only with non-static member functions
new and delete done only with static member functions
Other overloadable operators done with either friend, member, or ordinary functions
100
Unions
Union may have constructors and destructors but not virtual functions
Union cannot serve as base class, nor can it have base class
101
C++ and Access Modification (1 of 2)
With public inheritance destroys subtype relationship
Can’t broaden visibility
class B {public: int k;protected: int j, n;private: int i;};
102
C++ and Access Modification (2 of 2)
class D: public B {public: int m; B::n; //illegal protected access //cannot be widenedprivate: B::j; //otherwise default protected};
103
Summary of Inheritance (1 of 6)
Inheritance is mechanism of deriving new class from old one
Inherits base class code
Typically modifies & extends base class
Existing class added to or altered to create derived class
Inheritance allows creation of hierarchy of related ADTs that share code
104
Summary of Inheritance (2 of 6)
Class derived from existing class class classname:(public|protected|private)
optbasename
{ member declarations};
Keyword class can be replaced by keyword struct, with implication that members by default public
105
Summary of Inheritance (3 of 6)
Keywords public, private, and protected available as visibility modifiers for class members
Public member visible throughout its scope
Private member visible to other member functions within its own class
Protected member visible to other member functions within its class and any class immediately derived from it
Derived class has its own constructors, which invoke base class constructor
106
Summary of Inheritance (4 of 6)
Special syntax to pass arguments from th derived class constructor back to base class constructor
function header: basename (argument list)
Publicly derived class subtype of its base
Variable of derived class treated as if it were base class type
Pointer to base class can point to objects of publicly derived class type
107
Summary of Inheritance (5 of 6)
Reference to derived class may be implicitly converted to reference to public base class
Keyword virtual is function specifier that provides mechanism to select at run-time appropriate member function
Used only to modify member function declarations and is called overriding
Pure polymorphism
108
Summary of Inheritance (6 of 6)
Possible to declare reference to base class and initialize it to reference an object of publicly derived class
Public inheritance creates type hierarchyGenerality from additional implicit type
conversions
Run-time selection of overridden virtual functions
ADTs, inheritance, ability to process objects dynamically are essentials of OOP