Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.
-
Upload
ashley-camron-miles -
Category
Documents
-
view
213 -
download
0
Transcript of Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.
![Page 1: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/1.jpg)
Virtual Functions
Junaed Sattar
November 10, 2008Lecture 10
![Page 2: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/2.jpg)
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”
![Page 3: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/3.jpg)
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;
}
![Page 4: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/4.jpg)
Output
calling base constructor.
calling derived1 constructor.
calling derived2 constructor.
calling derived2 destructor.
calling derived1 destructor.
calling base destructor.
![Page 5: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/5.jpg)
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.
![Page 6: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/6.jpg)
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.
![Page 7: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/7.jpg)
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
![Page 8: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/8.jpg)
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
![Page 9: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/9.jpg)
Exampleclass 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; }};
![Page 10: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/10.jpg)
Output
int main() {B b; C c;A* pa1 = &b;A* pa2 = &c;// b.f();pa1->f();pa2->f();}
Outputs:
Class A
Class C
![Page 11: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/11.jpg)
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()
![Page 12: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/12.jpg)
So, why?
a hierarchy of geometric shape classes draws circles,
ellipses, rectangles etc
just use method draw throughout the hierarchy
Line
Rectangle Circle
Square Ellipse
draw()
draw()
draw()
draw()
draw()
![Page 13: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/13.jpg)
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
![Page 14: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/14.jpg)
“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
![Page 15: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/15.jpg)
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; }};
![Page 16: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/16.jpg)
Output
int main() {B b; C c;A* pa1 = &b;A* pa2 = &c;pa1->f();pa2->f();}
Outputs:
Class B
Class C
![Page 17: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/17.jpg)
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;...
};
![Page 18: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/18.jpg)
Continuing
class USBDevice: public ImagingDevice {...
public:USBDevice();virtual ~USBDevice();
...};
bool USBDevice::InitializeDevice(){ ... }bool USBDevice::UninitializeDevice(){ ... }bool USBDevice::GetImage(){ ... }void USBDevice::SaveImage(){ ... }
![Page 19: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/19.jpg)
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; }
}
![Page 20: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/20.jpg)
Virtual Destructor
int foo() {Base *b = new Derived();...delete b; // will not call destructor of d, as it
// should, (why?)}
![Page 21: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/21.jpg)
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
![Page 22: Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.](https://reader035.fdocuments.us/reader035/viewer/2022062715/56649da15503460f94a8d90f/html5/thumbnails/22.jpg)
Next
Generic programming with templates The Standard Template Library