© copyright eliyahu brutman programming techniques course version 1.0
Post on 20-Dec-2015
225 Views
Preview:
TRANSCRIPT
© Copyright Eliyahu Brutman
Programming Techniques Course
Version 1.0
© Copyright Eliyahu Brutman
Chapter 8 –More Inheritance
Version 1.0
© Copyright Eliyahu Brutman
More Inheritance - 3
Lets recall
What we have seen so far
Non-polymorphic inheritance (Object Based)
Inheritance for code reuse reasons
Reflects a relationship of Is-A
Inheritance means that the derived inherits its base class characteristics
The derived class can add to this characteristics of its own
For instance:
The layout of derived contains the layout of the base class
Class person
Class worker
nameGetName()
salaryCalculateSal()
© Copyright Eliyahu Brutman
More Inheritance - 4
Lets recall
We can invoke all inherited characteristics through the derived
For instance, we can ask the worker what is his name, even though he does not implement such a method
Worker w(…);
w.GetName();
The compiler resolves the call to Person::GetName()
If we implement such a method at the Worker class
It will be called (resolved to Worker::GetName())
Protected access keyword has been introduced
© Copyright Eliyahu Brutman
More Inheritance - 5
Lets Continue to Polymorphic Inheritance
Suppose we have a container of Employees We would like to iterate over all employees, without knowing which
specific kind they are, and ask them to calculate their salary (call their CalcSalary() method)
Each type has its own calculation algorithm, based on different considerations
Each object will invoke its relevant CalcSalary(), depending on its type
Class Employee
Class SalesPerson Class Executive Class Administrative
m_salaryv. CalcSalary()
v. CalcSalary() v. CalcSalary() v. CalcSalary()m_sales m_performance
© Copyright Eliyahu Brutman
More Inheritance - 6
Example
We want each element in the container to call its own CalcSalary() method as a function of the real object Employee Employee::CalcSalary() SalesPerson SalesPerson::CalcSalary() Executive Executive::CalcSalary() Administrative Administrative::CalcSalary()
Executive
Administrative
Administrative
Executive
Sales Person
Employee* employees[100];
© Copyright Eliyahu Brutman
More Inheritance - 7
Static and dynamic binding
In object-oriented programming languages in most cases the variables are bound to a specific type at compile time
Static binding Dynamic binding
The type of the variable can change at run time
Using pointers to classes related by inheritance
Executive exec;
Employee* emp = &exec;
Can be dangerous in some cases
© Copyright Eliyahu Brutman
More Inheritance - 8
Example
Definition:Single name denotes objects of different classes related by inheritanceAbility to manipulate derived objects using the interface defined in the base class
Example:class Employee { public:
void CalcSalary ();};class SalariedEmployee :public Employee{ public:
void CalcSalary ();};
© Copyright Eliyahu Brutman
More Inheritance - 9
Example
Employee *ep;
ep = new SalariedEmployee;
ep->CalcSalary(); Which function is called?
The function in Employee is called To avoid that we have to declare CalcSalary() as a virtual
function
virtual is a special keyword
© Copyright Eliyahu Brutman
More Inheritance - 10
Virtual Functions
Definition:Member function prefaced by the virtual specifier.Compiler generates the code that will select the appropriate function at runtime
Example:class Employee { public:
virtual void CalcSalary ();};
class SalariedEmployee:public Employee{ public:
virtual void CalcSalary ();};
virtual specifier needs to appear in the base class onlyHowever, typically specified also in subclusses
© Copyright Eliyahu Brutman
More Inheritance - 11
Examples
Employee *p0 = new Employee;
Employee *p1 = new SalariedEmployee;
p0->CalcSalary(); // calls Employee::CalcSalary()
p1->CalcSalary(); // calls SalariedEmployee::CalcSalary()
Any non-static member function except a constructor can be virtual
Virtual functions can also be friends of other classes Some compilers require the class destructor to be virtual if
a class contains any virtual functions
© Copyright Eliyahu Brutman
More Inheritance - 12
Virtual Functionsclass A {public: void x() {cout<<"A:x";}; virtual void y() {cout<<"A:y";};};
class B : public A {public: void x() {cout<<"B:x";}; virtual void y() {cout<<"B:y";};};
int main () { B b; A *ap = &b; B *bp = &b; b.x (); // prints "B:x" b.y (); // prints "B:y" bp->x (); // prints "B:x" bp->y (); // prints "B:y" ap->x (); // prints "A:x" ap->y (); // prints "B:y" return 0;};
Only matter with pointer or reference
Calls on object itself resolved staticallyb.y();
Look first at pointer/reference typeIf non-virtual there, resolve
staticallyap->x();
If virtual there, resolve dynamically
ap->y();Caller can force static resolution of a virtual function via scope operator
ap->A::y(); prints “A::y”
© Copyright Eliyahu Brutman
More Inheritance - 13
Combinations of virtual and non-virtual functions
Non-virtual function can call virtual function Example:
class Employee {
public:
void Display();
virtual void CalcSalary ();
};
class SalariedEmployee:public Employee{
public:
void Display();
virtual void CalcSalary ();
};
© Copyright Eliyahu Brutman
More Inheritance - 14
Example
void Employee::Display(){
CalcSalary();};
void SalariedEmployee::Display(){
CalcSalary();};
Employee *p0 = new SalariedEmployee;
p0->Display();
// calls SalariedEmployee::CalcSalary();
© Copyright Eliyahu Brutman
More Inheritance - 15
Example
It works the other way too
class Employee { public:
virtual void Display();void CalcSalary ();
};
class SalariedEmployee:public Employee{ public:
virtual void Display();void CalcSalary ();
};
Employee *p0 = new SalariedEmployee;p0->Display(); // calls Employee::CalcSalary();
© Copyright Eliyahu Brutman
More Inheritance - 16
Common Interface
Virtual functions in the base class provide common interface for all of its derived classes
Example:
class Employee { public:
long GetDepartment();long GetId();virtual void Display();virtual void Input ();virtual void CalcSalary ();
private:long id;long deptNum;
};
© Copyright Eliyahu Brutman
More Inheritance - 17
Example
class Polygon { protected: int width, height; public:
void set_values (int a, int b){ width=a; height=b; }virtual int area();
};
class Rectangle: public Polygon { public: int area (void) { return (width * height); }};
class Triangle: public Polygon { public: int area (void) { return (width * height / 2); } };
© Copyright Eliyahu Brutman
More Inheritance - 18
Example (cont.)
int main () {
Rectangle rect;
Triangle trgl;
Polygon * ppoly1 = ▭
Polygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << endl;
cout << ppoly2->area() << endl;
return 0;
}
© Copyright Eliyahu Brutman
More Inheritance - 19
Virtual Destructors
Destructor preceded by the virtual specifierCorrect destructor must be called
It is recommended that any class containing virtual functions should also have a virtual destructor
Example
BookItem needs a separate destructor to de-allocate the storage for title
class Item {
public:
virtual ~Item();
//...
};
class BookItem {
public:
virtual ~BookItem();
private:
char * title;
};
© Copyright Eliyahu Brutman
More Inheritance - 20
Pure Virtual
The Employee can define this method at the base class as pure virtual :
virtual int Employee::CalcSalary() = 0;
Meaning,
It wants all inheriting classes to implement their own implementation
We cannot instantiate an object of this class – it is said to be an Abstract Class
But we still can have pointers
© Copyright Eliyahu Brutman
More Inheritance - 21
Example
class Polygon { protected: int width, height; public:
void set_values (int a, int b){ width=a; height=b; }virtual int area()=0;
}; class Rectangle: public Polygon { public: int area (void) { return (width * height); }}; class Triangle: public Polygon { public: int area (void) { return (width * height / 2); } };
© Copyright Eliyahu Brutman
More Inheritance - 22
Example (cont.)
int main () {
Rectangle rect;
Triangle trgl;
Polygon * ppoly1 = ▭
Polygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << endl;
cout << ppoly2->area() << endl;
return 0;
}
© Copyright Eliyahu Brutman
More Inheritance - 23
Virtual Functionsclass A {public: virtual void x() = 0; virtual void y() = 0;};
class B : public A {public: virtual void x();};
class C : public B {public: virtual void y();};
int main () { A * ap = new C; ap->x (); ap->y (); delete ap; return 0;};
A is an Abstract Base ClassDeclares pure virtual functions (=0)
Derived classes override pure virtual methods
B overrides x(), C overrides y()Can’t instantiate class with declared or inherited pure virtual functions
A and B are abstract, can create a CCan still have a pointer to an abstract class type
Useful for polymorphism
© Copyright Eliyahu Brutman
More Inheritance - 24
Static Binding Vs. Dynamic Binding
Static Binding
Function call is resolved during compile time
CALL fixed value Dynamic Binding
During compile time we cannot know what address to jump to
It needs to be resolved during run-time
Depending on the type of the actual object This information is accessed via virtual pointer
Each object holds And via virtual table
Each class maintains
© Copyright Eliyahu Brutman
More Inheritance - 25
Dynamic Binding - Implementation
Executive
Administrative
Administrative
Executive
Sales Person
Executive Virtual Table
Sales Person Virtual Table
Executive::CalcSalary()
SalesPerson::CalcSalary()
Employee* employees[100];
© Copyright Eliyahu Brutman
More Inheritance - 26
Summary: Tips on Polymorphism
Push common code and variables up into base classesUse public inheritance for polymorphismPolymorphism depends on dynamic typing
Use a base-class pointer or reference if you want polymorphism
Use virtual member functions for dynamic overridingUse private inheritance only for encapsulationUse abstract base classes to declare interfacesEven though you don’t have to, label each virtual method (and pure virtual method) in derived classes
top related