1 / 22

Virtual Functions

Junaed Sattar November 10, 2008 Lecture 10. Virtual Functions. Constructor/Destructor Order. Destructors, constructors, and assignment operators are not inherited they may be called automatically were necessary Constructors are called from the “bottom up”

khanh
Download Presentation

Virtual Functions

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Junaed Sattar November 10, 2008 Lecture 10 Virtual Functions

  2. Constructor/Destructor Order • Destructors, constructors, and assignment operators are not inherited • they may be called automatically were necessary • Constructors are called from the “bottom up” • Destructors are called from the “top down”

  3. Example • class Base {public:Base() { cout << "calling base constructor." << endl; }~Base() { cout << "calling base destructor." << endl; }}; • class Derived1: public Base{public:Derived1() { cout << "calling derived1 constructor." << endl; }~Derived1() { cout << "calling derived1 destructor." << endl; }}; • class Derived2 :public Derived1{public:Derived2() { cout << "calling derived2 constructor." << endl; }~Derived2() { cout << "calling derived2 destructor." << endl; }}; • int main(){ Derived2 d; • }

  4. Output • calling base constructor. • calling derived1 constructor. • calling derived2 constructor. • calling derived2 destructor. • calling derived1 destructor. • calling base destructor.

  5. Virtual Functions • C++ matches a function call with the correct function definition at compile time • known as static binding • the compiler can match a function call with the correct function definition at run time • known as dynamic binding. • declare a function with the keyword virtual if you want the compiler to use dynamic binding for that specific function.

  6. Virtual Methods • Therefore, • a virtual function is a member function you may redefine for other derived classes, • can ensure that the compiler will call the redefined virtual function for an object of the corresponding derived class, • even if you call that function with a pointer or reference to a base class of the object. • A class that declares or inherits a virtual function is called a polymorphic class.

  7. Declaring virtual • prefix declaration with the virtual keyword • redefine a virtual member function in any derived class • this is called overriding • understand the contrast with overloading

  8. More on definition • overridden function must have same name and same parameter list • no need to use the virtual keyword again • return type can be different • if the parameter lists are different, they are considered different • in this case, it is not overridden, but hidden • hidden methods cannot be called

  9. Example • class A {public:virtual void f() { cout << "Class A" << endl; }}; • class B: public A { • public:void f(int) { cout << "Class B" << endl; }}; • class C: public B { • public:void f() { cout << "Class C" << endl; }};

  10. Output • int main() {B b; C c;A* pa1 = &b;A* pa2 = &c;// b.f();pa1->f();pa2->f();} • Outputs: • Class A • Class C

  11. Synopsis • b::f() is not allowed • it hides A::f() (a virtual function)‏ • not overloading (why?)‏ • method overloading must happen within the same class, not in inheritance hierarchies • c::f() is allowed • virtual, overrides A::f()‏

  12. So, why? • a hierarchy of geometric shape classes • draws circles, ellipses, rectangles etc • just use method draw throughout the hierarchy Line draw()‏ Rectangle Circle draw()‏ draw()‏ Square Ellipse draw()‏ draw()‏

  13. More why • to enforce a software design • developers must define their own implementation • e.g. ImagingDevice objects (webcam, firewire, disk images, movies ..)‏ • must acquire frames in their own way • should have uniform interface (hiding implementation details)‏ • use pure virtual methods

  14. “Pure”ly Virtual • a virtual function declared with no definition • base class contains no implementation at all • class containing a pure virtual function is an abstract class • similar to Java interfaces • cannot instantiate from abstract classes • enforces a design through inheritance hierarchy • inherited classes must define implementation

  15. Example • class A {public:virtual void f() = 0; // pure virtual}; • class B: public A { • public:void f() { cout << "Class B" << endl; }}; • class C: public B { • public:void f() { cout << "Class C" << endl; }};

  16. Output • int main() {B b; C c;A* pa1 = &b;A* pa2 = &c;pa1->f();pa2->f();} • Outputs: • Class B • Class C

  17. Another example • class ImagingDevice {protected: unsigned char *buffer; int width, height; ...public: ImagingDevice(); virtual ~ImagingDevice(); // virtual destructor ... virtual bool InitializeDevice() = 0; virtual bool GetImage()=0; virtual bool UninitializeDevice() = 0; virtual void SaveImage()=0; ...};

  18. Continuing • class USBDevice: public ImagingDevice { ...public: USBDevice(); virtual ~USBDevice();...};bool USBDevice::InitializeDevice(){ ... }bool USBDevice::UninitializeDevice(){ ... }bool USBDevice::GetImage(){ ... }void USBDevice::SaveImage(){ ... }

  19. Why virtual destructor? • for properly cleaning up dynamically allocated memory class Base{public: Base(){} ...}; class Derived: public Base { int *memory;public: Derived(){ memory = new int[1000]; } ~Derived(){ delete [] memory; }}

  20. Virtual Destructor • int foo() {Base *b = new Derived();...delete b; // will not call destructor of d, as it • // should, (why?)‏ • }

  21. Diagnosis • If not declared virtual, compiler uses type of pointer to decide which method to call • in this case, b is of type Base, so the Base destructor will get called • memory leak from d (how?)‏ • solution: always declare destructors virtual, even if no other virtual functions

  22. Next • Generic programming with templates • The Standard Template Library

More Related