Presentation is loading. Please wait.

Presentation is loading. Please wait.

Polymorphism From now on we will use g++!. Example (revisited) Goal: Graphics package Handle drawing of different shapes Maintain list of shapes.

Similar presentations


Presentation on theme: "Polymorphism From now on we will use g++!. Example (revisited) Goal: Graphics package Handle drawing of different shapes Maintain list of shapes."— Presentation transcript:

1 Polymorphism From now on we will use g++!

2 Example (revisited) Goal: Graphics package Handle drawing of different shapes Maintain list of shapes

3 Solution #1 class Shape { public: enum Type { e_square, e_circle, e_triangle }; Shape( Type t, Point center, double width, double height); void draw(); double area(); … private: Type m_type; Point m_center; … };

4 Solution #1 This solution gives a nice “wrapping” to the solution we consider in C. (switch command) Pros: Simple, direct Cons: Adding new shapes requires changing all procedures that deal with shape. Require fat interface in order to support all kinds of shapes. No type checking. Unsafe!

5 Solution #2 – different classes class Square { public: void draw(); double area(); … }; class Circle { public: void draw(); double area(); … };

6 Solution #2 – Discussion Each shape has its own implementation We can easily add new shapes However, Shapes are different types One cannot view them as part of the same class

7 Solution #3 - Inheritance class Shape { public: void draw(); double area(); … }; class Square: public Shape { public: void draw(); double area(); … }; class Circle: public Shape { public: … void draw(); double area(); … }; …

8 Solution #3 Now we can write code such as: Shape* myShapes[2]; myShapes[0] = new Circle(); myShapes[1] = new Square(); … What will happen when we call myShapes[0]->draw(); Lets test … see shapes.cpp.shapes.cpp

9 What is going on? When we write: Circle circle; circle.draw(); The compiler calls Circle::draw(); When we write: Shape* p = new Circle(); p->draw(); The compiler calls Shape::draw() Why? *p has type Shape

10 Class Hierarchy class Base { public: … void foo(); void bar(); … }; class Derived: public Base{ public: … void bar(); … }; Derived obj; obj.foo(); Calls Base::foo() Derived does not implement this method obj.bar(); Calls Derived::bar() Two implementations, the more specific is used

11 Inheritance & Overloading Derived inherits the method foo () from Base. –The inherited class is using methods of the base class Derived overloads the implementation of bar (). –This mechanism allows an inherited class to specialize the implementation.

12 Static resolution How does the compiler determine which method to call? Static Resolution: Based on the type of the variable. –Not the type of the object! The compiler finds the most specific implementation of the method, and calls it.

13 Static resolution Example Circle* circle = new Circle(1,1,2); Square* square = new Square(2,2,1); Shape* myShapes[2]; myShapes[0] = circle; myShapes[1] = square; circle->draw(); // Calls Circle::draw() square->draw(); // Calls Square::draw() myShapes[0]->draw(); // Calls Shape::draw() myShapes[1]->draw(); // Calls Shape::draw()

14 Dynamic Resolution This is clearly not what we want to do in this example. A more desirable here solution, Dynamic resolution (Polymorphism): Based on the type of the object. Determined at run time. [Java Like!]

15 Dynamic Resolution Cont The virtual keyword states that the method can be overloaded in a dynamic manner. class Base { public: … virtual void bar(); … } class Derived: public Base { public: … virtual void bar(); … }

16 Solution #4: dynamic resolution Returning to the shapes example, using virtual methods gives the desired result See Shapes- virtual.cppvirtual.cpp

17 Virtual Methods Class Base defines a virtual method foo() The resolution of foo() is dynamic in all subclasses of Base. –If the subclass Derived overloads foo(), then Derived::foo() is called –If not, Base::foo() is called [See nested.cpp]nested.cpp

18 Underneath the Hood: Inheritance class Base { … private: double m_x; int m_a; }; class Derived : public Base { … private: double m_z; }; class Base a; class Derived b; m_x m_a m_z m_x m_a a: b: Base

19 Pointing to an Inherited Class class Derived b; class Base* p = &b; When using *p, we treat b as though it was a Base object The compiler cannot know if *p is from a derived class or not. m_x m_a m_z b: p:

20 Implementation of Virtual Methods Possible approach: If foo() is a virtual method, then each object has a pointer to the implementation of foo() that it uses Essentially the solution we used in our C implementation Cost: Each virtual method requires a pointer Large number of virtual methods  waste of memory

21 Implementation of Virtual Methods Alternative solution: Each object has a pointer to an array of function pointer This array points to the appropriate functions Cost: For each class, we store one table Each object contains one field that points to the right table

22 Example class A { public: virtual void f1(); virtual void f2(); int m_a; }; class B: public A { public: virtual void f1(); virtual void f3(); void f4(); int m_b; }; … A a1, a2; B b; class A { public: virtual void f1(); virtual void f2(); int m_a; }; class B: public A { public: virtual void f1(); virtual void f3(); void f4(); int m_b; }; … A a1, a2; B b; void A::f1 { //... }; void A::f1 { //... }; void A::f2 { //... }; void A::f2 { //... }; void B::f1 { //... }; void B::f1 { //... }; VTBLs A B m_a a1: m_a m_b b: m_a a1: void B::f3 { //... }; void B::f3 { //... }; f1 f2 f3 f1 f2

23 Virtual - Recap Virtual controls whether to use static or dynamic resolution Once a method is virtual, it must remain so throughout the hierarchy Calling a virtual method is more expensive than standard calls –Two pointers are “chased” to get to the address of the function.

24 Destructors & Inheritance class Base { public: ~Base(); }; class Derived : public Base { public: ~Derived(); }; Base *p = new Derived; … delete p; Which destructor is called? [see destruct.cpp]destruct.cpp

25 Virtual Destructor Destructor is like any other method The example uses static resolution, and hence not the intended destructor is called To fix that, we need to declare virtual destructor at the base class! See destruct-virt.cppdestruct-virt.cpp Once you declare virtual destructor, derived class must declare a destructor.

26 Polymorphism & Inheritance C++ allows to use class hierarchy to implement polymorphic code. Points of care: Choice of virtual methods. –Run time considerations efficiency. Use of virtual destructor for base class!

27 Shapes & Sizes Revisiting our example, we write class Shape { public: … virtual ~Shape(); // virtual destructor virtual void draw(); // virtual method virtual double area(); // also … }; How do we implement Shape::draw() ?

28 Inheritance & Abstract Classes In this example, we never want to deal with objects of type Shape –Shape serves the role of an interface All shapes need to be specific shapes that are instances of derived classes of Shape How do we enforce this? Simple mechanism: void Shape::draw() { assert(false); // we should never call this method }

29 Abstract Classes We can specify that Shape::draw() does not exist class Shape { public: … virtual ~Shape(); // virtual destructor virtual void draw() = 0; // pure virtual virtual double area() = 0; // Also … };

30 Abstract Classes We cannot create objects of a Pure Virtual class Shape* p; // legal Shape s; // illegal Circle c; // legal p = &c; // legal p = new Shape; // illegal

31 Virtual Methods - Tips If you have virtual methods in a class, always declare its destructor virtual! Never call virtual methods during construction and destruction! (invalid object state) Use virtual methods Duplicate() and Create() for implementing “virtual constructors”. Use pure abstract classes to define interfaces. Use inheritance with care: Be sure that this is the appropriate solution.


Download ppt "Polymorphism From now on we will use g++!. Example (revisited) Goal: Graphics package Handle drawing of different shapes Maintain list of shapes."

Similar presentations


Ads by Google