C & C++ Programming - Understanding Inheritence
#pragma once
#include "iostream"
using namespace std;
class CComposition1
{
public:
CComposition1()
{
cout << "Composition1 CTOR" << endl;
}
~CComposition1()
{
cout << "CComposition1 DTOR" << endl;
}
};
class CComposition2
{
public:
CComposition2()
{
cout << "CComposition2 CTOR" << endl;
}
~CComposition2()
{
cout << "CComposition2 DTOR" << endl;
}
};
class CBaseEx1
{
public:
CBaseEx1()
{
cout << "BASE CTOR" << endl;
}
virtual ~CBaseEx1()
{
cout << "BASE DTOR" << endl;
}
};
class CDerivedEx1 : public CBaseEx1
//class CDerivedEx1 : protected CBaseEx1 // This is not allowed
//class CDerivedEx1 : private CBaseEx1
{
public:
CDerivedEx1(CComposition1& f_objComposition1, CComposition2& f_objComposition2)
: m_objComposition1(f_objComposition1),
m_objComposition2(f_objComposition2)
{
cout << "DERIVED CTOR" << endl;
}
~CDerivedEx1()
{
cout << "DERIVED DTOR" << endl;
}
private:
CComposition1& m_objComposition1;
CComposition2& m_objComposition2;
};
//////////////////////////////////////////////////////////////////////
// Implementation file for class CBaseEx2
#pragma once
#include "iostream"
using namespace std;
class CBaseEx2
{
// Construction / Destruction
public:
// Default Constructor
explicit CBaseEx2(int);
// Destructor
virtual ~CBaseEx2();
CBaseEx2(const CBaseEx2& obj)
{
cout << "Copy construtor is called\n";
}
const CBaseEx2& operator = (const CBaseEx2& obj)
{
cout << "Assignment Operator is called\n";
return obj;
}
};
class CDerive : public CBaseEx2
{
// Construction / Destruction
public:
// Default Constructor
CDerive(int);
// Destructor
~CDerive();
};
CBaseEx2::CBaseEx2(int nData)
{
cout << "Base Class Constructor is called\n";
cout << nData << endl;
}
CBaseEx2::~CBaseEx2()
{
cout << "Base Class Destructor is called\n";
}
//////////////////////////////////////////////////////////////////////
// Implementation file for class CDerive
CDerive::CDerive(int nData)
: CBaseEx2(nData)
{
cout << "Derived Class Constructor is called\n";
}
CDerive::~CDerive()
{
cout << "Derived Class Destructor is called\n";
}
//////////////////////////////////////////////////////////////////////
// Implementation file for class CBaseEx3
#pragma once
#include "iostream"
using namespace std;
class CBaseEx3
{
// Construction / Destruction
public:
// Default Constructor
CBaseEx3();
// Destructor
virtual ~CBaseEx3();
public:
virtual void VirtualFunction1();
//virtual void PureVirtualFunction() = 0;
// static virtual void VirtualFunction2(); // Cannot define STATIC -
// Error: virtual used for static member function
void NormalFunction();
};
class CDerivedEx3 : public CBaseEx3
{
// Construction / Destruction
public:
// Default Constructor
CDerivedEx3();
// Destructor
~CDerivedEx3();
public:
virtual void VirtualFunction1();
//void PureVirtualFunction();
//void VirtualFunction2(); // Unless a function is not defined in the base
class "virtual"
// same name with different return type or argument can be used.
// Also this can be defined Static
void NormalFunction();
};
CBaseEx3::CBaseEx3()
{
cout << "Base Class Constructor is called\n";
}
CBaseEx3::~CBaseEx3()
{
cout << "Base Class Destructor is called\n";
}
void CBaseEx3::VirtualFunction1()
{
cout << "Virtual function in base class\n";
}
void CBaseEx3::NormalFunction()
{
cout << "Normal function in base class\n";
}
/*void CBaseEx3::PureVirtualFunction()
{
cout << "Pure Virtual function in base class\n"; }*/
/*
void CBaseEx3::VirtualFunction2()
{
cout << "Base Class is called:" << 20 << endl;
}*/
//////////////////////////////////////////////////////////////////////
// Implementation file for class CDerivedEx3
CDerivedEx3::CDerivedEx3()
{
cout << "Derived Class Constructor is called\n";
}
CDerivedEx3::~CDerivedEx3()
{
cout << "Derived Class Destructor is called\n";
}
void CDerivedEx3::VirtualFunction1()
{
cout << "Virtual function in derive class\n";
}
void CDerivedEx3::NormalFunction()
{
cout << "Normal function in derive class\n";
}
/*
void CDerivedEx3::PureVirtualFunction()
{
cout << "Pure Virtual function in derive class\n";
}
void CDerivedEx3::VirtualFunction2()
{
cout << "Derive Class is called:" << 10 << endl;
}
*/
//////////////////////////////////////////////////////////////////////////////////
void VirtualFunctionCall(CDerivedEx3& objDerivePass, CBaseEx3& objBasePass)
{
CBaseEx3 *objBase;
CDerivedEx3 *objDerive = NULL;
// Without initialise execution error.
// objDerive->VirtualFunction2();
// Assigning the Base class object to the Derive Class
objBase = &objDerivePass; // UPCASTING
objBase->VirtualFunction1(); // If Function1 is defined as virtual than calls
the
// derived class function, ie Dynamic Binding.
// Else the Base class function will be called.
// Assigning the Derive Class object to the Base Class
//objDerive = &objBasePass; // This conversion is not possible as base class
object
// doesn't know about the derived class object.
//objDerive->VirtualFunction2(); Not possible with above declaration
}
void TestPolymorphism(CBaseEx3* objPoly)
{
objPoly->VirtualFunction1();
objPoly->NormalFunction();
}
// Inheritance.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Inheritance1.h"
#include "Inheritance2.h"
#include "Inheritance3.h"
void Test1()
{
CComposition1 l_objComposition1;
CComposition2 l_objComposition2;
cout << "*****************************************\n";
cout << "Initialisation for derived object" << endl;
//CDerivedEx1 objDerived(l_objComposition1, l_objComposition2);
//CDerivedEx1 *objDerived = new CDerivedEx1(l_objComposition1, l_objComposition2);
//delete objDerived;
CBaseEx1 *objBase = new CDerivedEx1(l_objComposition1, l_objComposition2);
delete objBase;
cout << "Exit for derived object" << endl;
cout << "*****************************************\n";
//CDerivedEx1 obj(2); // Once the CTOR is written for a class there is no
default CTOR.
// CTOR with same signature should be called through any derive
// class CTOR.
//Cbase* objB = new CDerivedEx1(2); // Base class shd have virtual destructor
for proper
// of DTOR of the derived classes
//delete objB;
}
void Test3()
{
// Whenever the object is created the constructor
// and destructor is called automatically. And it
// can access only the public data of a class.
// If a pure vitual function is defined in a class than object of that
// class cannot be created. While Object pointer can be created and
// cannot be initialise to the base class, however can be initialise
// to the derived classes.
// 1:- CBaseEx3 *objBase = new CBaseEx3(); // Not Allowed
// 2:- CBaseEx3 *objBase = new CDerivedEx3(); // Allowed
// Creating Object
cout << "1.\n";
CBaseEx3 objBase; // This will work only if the base class isnot defined
ABSTRACT
cout << "**************************\n";
cout << "2.\n";
CDerivedEx3 objDerive;
// In this case Base CTOR -> Derive CTOR ->
// -> Derive DTOR -> Base DTOR is called...
cout << "**************************\n";
//objBase.VirtualFunction(); // Not Allowed for abstract base classes
//objDerive.VirtualFunction1();
//objDerive.PureVirtualFunction();
cout << "3.\n";
CBaseEx3 *ptrBase = new CBaseEx3(); // Not Allowed if class is abstract and
delete is needed to call explicitly
cout << "**************************\n";
cout << "4.\n";
CBaseEx3 *ptrDeriveAssignedtoBase = new CDerivedEx3(); // Allowed -- UPCASTING
cout << "**************************\n";
cout << "5.\n";
//CDerivedEx3 * ptrBaseAssignedtoDerive = new CBaseEx3(); // Not Allowed
as Base Class doesnot Know About Derived Class
// DOWNCASTING
// Not Allowed - Because Base class doesn't know
// about the implementation of derive
cout << "**************************\n";
// Downcasting Not allowed
//ptrBase = (CDerivedEx3 *) &objDerive; // Error in deleting
//ptrBase->VirtualFunction1();
cout << "6.\n";
CDerivedEx3 *ptrDerive = new CDerivedEx3();
//ptrDerive = (CDerivedEx3 *) &objBase; // Error in deleting
cout << "**************************\n";
//ptrDerive = (CDerivedEx3 *) &objDerive; // Error in deleting
// ptrDerive->VirtualFunction1();
delete ptrBase;
delete ptrDeriveAssignedtoBase ;
delete ptrDerive;
//VirtualFunctionCall(objDerive, objBase);
cout << "=====================================================\n";
cout << "P O L Y M O R P H I C F U N C T I O N\n";
CBaseEx3 *objPoly = new CDerivedEx3;
TestPolymorphism(objPoly);
}
int _tmain(int argc, _TCHAR* argv[])
{
Test1();
CBaseEx2 obj('a');
//CBaseEx2 obj = 'a'; // implicit conversion to int => Make CBaseEx2 CTOR
explicit
CBaseEx2 obj2(2);
obj2 = obj;
Test3();
return 0;
}