Presentation is loading. Please wait.

Presentation is loading. Please wait.

Object Oriented Programming Elhanan Borenstein Lecture #7.

Similar presentations


Presentation on theme: "Object Oriented Programming Elhanan Borenstein Lecture #7."— Presentation transcript:

1 Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #7

2 Agenda Inheritance Polymorphism

3 Inheritance & Polymorphism

4 Inheritance Example class Base1 { int var1; public: Base1() {…} // constructor void OldFunc() {…} void Init() {…} }; class Derived1 : [public|protected|private] Base1 { int var2; public: Derived1() {…} // constructor void Init() {…} // override void Do(){…} };

5 Inheritance When inheriting a class, we inherit all its members and they will be included in the derived class: Somewhat similar to object data members (embedded): To differentiate, we can check the logics behind the implemented entities:  Inheritance: The derived class is a type of the base class.  Inner class: The inner class is a part of the external class. The Logic behind Inheritance Base (father) Additions Derived (son)  (SIZE?) Additions embedding class inner object

6 Inheritance Understanding Inheritance - Example class GraphicItem { int color; public: GraphicItem() {…} // constructor void Draw() {…} void ChangeColor(int n_clr) {…} }; class CPoint : public GraphicItem { int m_x, m_y; public: CPoint() {…} // constructor void Draw() {…} // override void Align(){…} }; … GraphicItem G, *pG; CPoint P, *pP; … G = P; P = G; pG = pP; pP = pG; …

7 Inheritance All the data members of the base class also exists in the derived class. But…:  There are cases where we cannot access these members.  They will still be included in the derived object size. When won’t we be able to access the base class members:  Hiding – The derived class has defined a data member with the same name. We can still access the hidden data member using its full name (base_class::member)  Private Permissions – Any private member of the base class cannot be accessed in the derived class. Note: the private data member is still included in the derived class (and can be accessed using a public method of the base class). A good design, will include in the base class only data members that are common (and can be accessed) by all derived classes. Accessing the Base Class Data Members

8 Inheritance The derived class also inherit all the base class methods. The derived class can override inherited methods. When activating a method of an object from the derived class: > If the inherited method was not overridden the base method (from the base class) will be activated. > If the method was overridden in the derived class, the method of the derived class will be activated.  We can still activate the base method using its full name.  It is very common to include a call to the base method from the derived method. C’tor, D’tor and C.C. are the only methods that have a different behavior when inherited. Using the Base Class Member Functions

9 Inheritance C’tor and D’tor are not inherited (WHY?). Constructing an object of the derived class, always activates first the C’tor of the base class (to create the base part of the object). The order is thus as follows:  The C’tor of the base class is activated.  The additional data members of the derived class are created.  If some of the data members are objects  the C’tor of each such object is activated.  The C’tor of the derived class is activated The order of the D’tor’s activation is of course reversed. What if the C’tor of the base class has parameters? C’tor and D’tor in Inherited Classes

10 Inheritance If the C’tor of the base class has parameters we must use the initialization line (in an analogous manner to object data members): C’tor and D’tor in Inherited Classes – Cont’ class CRect { CPoint pnt1, pnt2; public: CRect(int x1, int y1, …) : pnt1(x1,y1), pnt2(0,0) {…} // c’tor }; class CGraphicRect : public GraphicItem { … public: CGraphicRect(int color) : GraphicItem(color) {…} // c’tor }; Embedded Objects Inheritance

11 The assignment operator in not inherited. If the derived class did not implement the assignment operator, when copying, the base class assignment operator will not be activated but rather the default assignment operator of the derived class. But… as part of the default assignment operator action, (when the base class members should be copied), the base class assignment operator will be activated. Example: Stack Assignment Operator (=) in Inherited Classes

12 Inheritance Rule of thumb: A derived class should implement an assignment operator only if it performs dynamic allocation. The same is true for the copy constructor and the destructor. Remember the triplet:  Copy Constructor  Destructor  Assignment Operator Example: AB.cpp Assignment Operator (=) in Inherited Classes

13 Polymorphism The Polymorphism mechanism allows for an action to performs differently according to the object type, while being transparent to the programmer. As we recall, a pointer to the base class can also point to objects from a derived class.  There will be no data loss  We will be able to activate methods on that object, only if they exist in the base class. The issue is however, which method will be activated (base or derive)? Introduction

14 Polymorphism Example class Employee { double Salary; public: void Print() const {…} void RaiseSalary (double r) { Salary += r; Print(); } }; class Manager : public Employee { … public: void Print() {…} }; main () { Employee *pE; pE = new Manager; pE->Print(); … Manager m; m.Print(); m.RaiseSalary(); }

15 Polymorphism Typing – Identifying the type of the object we manipulate. Binding – Associating the memory address of functions/variables. Static binding – upon compilation (like in C) Dynamic binding – upon runtime (like in Java) In C++ binding is static unless instructed otherwise. Static & Dynamic Typing/Binding

16 Polymorphism When activating a method through a pointer to the base class:  if the method was not defined as virtual:  A Static Binding is performed (on compilation)  The base class method will be activated  If the method was define as virtual:  A Dynamic Binding will be performed (on runtime)  The method of the appropriate class will be activated. Example: Humus_Ashkara Virtual Methods and Dynamic Binding

17 Polymorphism The only place in the application we checked the object type, was in the input function (object creation). Our goal in polymorphism is to avoid checking the actual type of an object by using virtual methods and operators. The virtual property in the application was used twice:  Directly activating a method (in the main) through a pointer to the base class  the appropriate method was activated.  The print method of the base class is using virtual methods and using the appropriate methods according to the object which activated the print method. This paradigm is called GENERIC ALGORITHMS!!! Note that we have used one array to store and handle objects of various types. We have actually implemented a General Container (can we do that in C?) Humus_Ashkara – A few Notes

18 Polymorphism General Containers support the implementation of data structures using pointers to Data* while actually storing objects that are derived from Data. Examples: Humus, MFC objects (CObArray), Graphic objects… General Containers Generic Algorithms forms a skeleton of the algorithms by calling methods which will be implemented differently by each derived classes. Example: Print, Draw Object, Calc3DVolume. Generic Algorithms

19 Polymorphism The Virtual property is inherited. If a methods was defined in the base class as virtual, it will be virtual in all its derived classes. However, it is recommended to include the virtual keyword also in the derived classes. If objects in the containers has a non-trivial destructor, it must be virtual (WHY?).  Rule of thumb: If virtual inheritance is used, we must implement a virtual destructor in the base (even if it will be empty). When activating a virtual method from within the c’tor or d’tor of the base class, the base class method will be activated (even in the object created/destroyed is of a derived class). WHY? Virtual Methods – Guidelines

20 Polymorphism There are cases (especially when we implemented a General Container), where there is no intention to actually create an object of the base class. In such a case, we wish to:  Avoid implementation of some of the base class virtual methods (which will be overridden by the derived classes anyway).  Prevent the programmer from creating objects of the base class. The solution is Pure Functions and Abstract Classes:  A pure function is a virtual function, declared in the base class only for the purpose of implementing it in the derived classes. To define a function as pure we will add =0 in the prototype.  A class with one or more pure function is automatically an abstract class  objects of that class cannot be created or passed ByVal. Example: abstract Abstract Classes

21 Polymorphism Dynamic binding is implemented by a virtual functions table. Each object that includes a virtual function will also include a pointer to this table (usually two bytes pointer): Calling a virtual function will thus require two memory calls: C obj;  How Does Dynamic Binding Work? class A { int a; public: virtual void f() {…} virtual void h() {…} virtual void g() {…} }; class B : public A { int b; public: virtual void g() {…} }; class C : public B { int c; public: virtual void h() {…} }; a vfptr b c A::f() B::g() C::h() C vftable

22 Polymorphism Try that… class A { public: virtual void f() {cout<<“A”;} void h() {cout<<“a”;} virtual void g() { f(); h(); } }; class B : public A { public: virtual void f() {cout<<“B”;} void h() {cout<<“b”;} }; class C : public B { public: virtual void f() {cout<<“C”;} void h() {cout<<“c”;} }; main() { B* p; p = new C; p->g(); p->h(); }; 1. Abc 2. Cab 3. Acb 4. Cac 5. Ccc

23 Polymorphism There are scenarios where we are required to check what is the real object type that we actually hold. (WHEN?) We can implement our own mechanism using a virtual function called Type(). Alternatively, the operator typeid can be used.  #include is required (not an integral part of C++)  Setting the project to work with RTTI is required  The return value is an object of type typeinfo, that supports the method name() and the operator ==  typeid also works on fundamental data types (int, float, etc.) Example: typeinfo Runtime Type Information

24 Polymorphism Dynamic casting is a safe method to perform casting to a specific derived class while checking if it actually points to an object of that class. There are cases where dynamic_cast has an advantage over typeid. For example: Dynamic Casting class A { }; class B : public A { void Do() {…} }; class C ; public B { }; void main() { A* pa = new C; if (typeid(*pa)==typeid(B)) ((B*)pa)->Do(); B* pb=dynamic_cast (pa); if (pb) pb->Do(); }

25 Questions?


Download ppt "Object Oriented Programming Elhanan Borenstein Lecture #7."

Similar presentations


Ads by Google