Index

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;
}

Index