Escolar Documentos
Profissional Documentos
Cultura Documentos
Constructor/Destructor Order
Constructors are called from the bottom up Destructors are called from the top down
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; }
Output
calling base constructor.
calling derived1 constructor.
Virtual Functions
C++ matches a function call with the correct function definition at compile time
the compiler can match a function call with the correct function definition at run time
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.
Declaring virtual
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
in this case, it is not overridden, but hidden hidden methods cannot be called
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; } };
Output
int main() { B b; C c; A* pa1 = &b; A* pa2 = &c; // b.f(); pa1->f(); pa2->f(); }
Outputs:
Class A Class C
Synopsis
method overloading must happen within the same class, not in inheritance hierarchies
c::f() is allowed
So, why?
Line
draw()
Rectangle
draw()
Circle
draw()
Square
draw()
Ellipse
draw()
More why
Purely Virtual
similar to Java interfaces cannot instantiate from abstract classes inherited classes must define implementation
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; } };
Output
int main() { B b; C c; A* pa1 = &b; A* pa2 = &c; pa1->f(); pa2->f(); } Outputs: Class B Class C
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; ... };
Continuing
class USBDevice: public ImagingDevice { ... public: USBDevice(); virtual ~USBDevice(); ... }; bool USBDevice::InitializeDevice(){ ... } bool USBDevice::UninitializeDevice(){ ... } bool USBDevice::GetImage(){ ... } void USBDevice::SaveImage(){ ... }
class Base{ public: Base(){} ... }; class Derived: public Base { int *memory; public: Derived(){ memory = new int[1000]; } ~Derived(){ delete [] memory; } }
Virtual Destructor
int foo() { Base *b = new Derived(); ... delete b; // will not call destructor of d, as it // should, (why?) }
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?)
Next