- All instance(non static) data members of Base Class (super class) always becomes part of Derived Class (sub class). This is regardless of what access has been given to the derived class.
- All instance methods of Base class can work for derived class object even constructor or destructor
- When object of the Derived class calls the instance method of derived class or base class, it's address is always passed to it and it gets collected as this pointer.
- When Object of derived class calls instance method of derived class, the object address is passed to the method. And when this method calls the instance method of the base class, the same address is passed to that methods also. Both the method will work on the same object.
- When object of derived class calls instance method of base class, the object address is passed to it. Because of this, when required, the derived function can be called back because we have the derived object pointer.
- Derived class constructor always calls base class constructor before derived class constructor is executed.
- Derived class deconstructor always calls base class deconstructor after derived class destructor is executed.
- The address of the object received by the derived constructor or deconstructor is always passed to base class constructor or deconstructor.
- Pointer of the type base class can hold address of derived class object (this is how we achieve polymorphism).
- When delete is applied on base class pointer holding address of derived class object, deconstructor of the base is called and deconstructor of the derived class is not called. This results into memory leaks if the destructor of derived class wanted to cleanup dynamically allocated memory. In such cases, always make deconstructor of the base class virtual. This results into late-bound call for deconstructor. This way, derived class deconstructor is called first, followed by a call to base class deconstructor.
Template method design patten is heavily used by GUI application. They require a template UI element to be created in case the derived class has not defined the creationg of that UI elements.
From the point 5 above, we can implement template pattern. Code below demostrate that.
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// GUI framework
// This is template, which does not define all methods
class Window
{
public:
virtual vector<string> getStatusBarItems(){
return vector<string>(); // Empty
}
virtual vector<string> getTitleBarItems(){
return vector<string>(); // Empty
}
void Create(/* this = & of NotepadWindow Object*/){
// Create window frame
// Create window title bar
// Get title bar items
this->getTitleBarItems(); // Late bound call if overridden, call delegated to the derived class
// Create window status bar
// Get status bar item
this->getStatusBarItems(); // Late bound call if overridden
}
};
// Now we need to define window corresponding to notepad
class NotePadWindow : public Window
{
public:
vector<string> getTitleBarItems() override{ // As of now, override is keyword that does nothing
vector<string> menuItem = { "File", "Edit" };
return menuItem;
}
};
class PaintWindow : public Window
{
public:
vector<string> getTitleBarItems() override{ // As of now, override is keyword that does nothing
vector<string> menuItem = { "File", "Colors" };
return menuItem;
}
vector<string> getStatusBarItems() override{
vector<string> statusBar = { "ColorBar" };
return statusBar;
}
};
class Application
{
public:
void Start(Window *w){
w->Create();
}
};
// Our code
void SartingPointofOurCode(){
Application app;
app.Start(new NotePadWindow()); //StatusBar for notepad will be blank
app.Start(new PaintWindow());
}
int main()
{
SartingPointofOurCode();
return 0;
}