Showing posts with label inheritance. Show all posts
Showing posts with label inheritance. Show all posts

Extending enums

There might come a scenario where you want to include an enum into a another one where the first one is a subset.

#include
struct enum_a {
     enum constant {
         a, b, c, d,
         end_of_enum_a = d
     };
};
struct enum_b : public enum_a {
     enum constant {
         e = end_of_enum_a + 1,
         f, g, h
     };
};
int main() {
     std::printf("enum_a: a(%d), b(%d), c(%d), d(%d)\n",
         enum_b::a, enum_b::b, enum_b::c, enum_b::d);
     std::printf("enum_b: e(%d), f(%d), g(%d), h(%d)\n",
         enum_b::e, enum_b::f, enum_b::g, enum_b::h);
     return 0;
}

Inheritance to the rescue. :-)

Virtual Base class Inheritance


Came across this interesting case of multiple base class inheritance which can result in compilation errors.

Figure above demonstrates the ambiguity that can occur in diamond inheritance. The program defines class Base, which contains pure virtual function print. Classes DerivedOne and DerivedTwo each publicly inherit from class Base and override the print function. Class DerivedOne and class DerivedTwo each contain what the C++ standard refers to as a base-class subobject—i.e., the members of class Base in this example.

Class Multiple inherits from both classes DerivedOne and DerivedTwo. In class Multiple, function print is overridden to call DerivedTwo’s print.

Function main declares objects of classes Multiple, DerivedOne and DerivedTwo. main also declares an array of Base * pointers. Each array element is initialized with the address of an object. An error occurs when the address of both—an object of class Multiple—is assigned to array[ 0 ]. The object both actually contains two subobjects of type Base, so the compiler does not know which subobject the pointer array[ 0 ] should point to, and it generates a compilation error indicating an ambiguous conversion.

The problem of duplicate subobjects is resolved with virtual inheritance. When a base class is inherited as virtual, only one subobject will appear in the derived class—a process called virtual base-class inheritance.



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example showing virtual base class inheritance
//http://www.deitel.com/articles/cplusplus_tutorials/20060225/virtualBaseClass/index.html

#include <iostream>
using std::cout;
using
std::endl;

// class Base definition
class Base
{

public
:
virtual
void print() const = 0; // pure virtual
}; // end class Base

// class DerivedOne definition
//class DerivedOne : public Base - REF1
class DerivedOne : virtual public Base
{

public
:
// override print function
void print() const
{

cout << "DerivedOne\n";
}
// end function print
}; // end class DerivedOne

// class DerivedTwo definition
//class DerivedTwo : public Base - REF2
class DerivedTwo : virtual public Base
{

public
:
// override print function
void print() const
{

cout << "DerivedTwo\n";
}
// end function print
}; // end class DerivedTwo

// class Multiple definition
class Multiple : public DerivedOne, DerivedTwo
{

public
:
// qualify which version of function print
void print() const
{

DerivedTwo::print();
}
// end function print
}; // end class Multiple

int
main()
{

Multiple both; // instantiate Multiple object
DerivedOne one; // instantiate DerivedOne object
DerivedTwo two; // instantiate DerivedTwo object
Base *array[ 3 ]; // create array of base-class pointers

array[ 0 ] = &both; // ERROR - ambiguous if REF1 and REF2 used
array[ 1 ] = &one;
array[ 2 ] = &two;

// polymorphically invoke print
for ( int i = 0; i < 3; i++ )
array[ i ] -> print();

return
0;
}
// end main

The output is as follows:


Example of Virtual Functions

The following is a simple example of Virtual functions. There is a Shape class which is the base class and three other classes are derived from the Shape class. The Circumference method in the base class is 'pure virtual' so it has to be defined in the derived classes else the compiler will complain about the class being abstract. Note that even if a base class has a single pure virtual function, it would become as an Abstract Base class.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This shows an example of C++ virtual function/methods
//This example also covers a pure virtual method
//This also shows an example of Inheritance
#include<iostream>

using namespace
std;

//Base Class
class Shape {
public
:
virtual
void Area(int length, int breadth)
{

cout<<"Shape: Area = "<<length * breadth<<endl;
}

virtual
void Circumference(int length, int breadth) = 0; //pure virtual
};

//Derived class - Inherits Shape as Public
class Rectangle : public Shape {
public
:
void
Circumference(int length, int breadth)
{

cout<<"Rectangle: Circumference = "<<2*(length + breadth)<<endl;
}
};


//Derived class - Inherits Shape as Public
class Square : public Shape {
public
:
//Overloaded Area because for Square length = breadth
void Area(int length)
{

Shape::Area(length, length);
}

//Overloaded Circumference because for Square length = breadth
void Circumference(int length)
{

cout<<"Square: Circumference = "<<(4 * length)<<endl;
}

void
Circumference(int length, int breadth)
{

Circumference(length);
}
};


//Derived class - Inherits Shape as Private as Area and Circumference
//for Square is very different from the Base class
class Circle : private Shape {
public
:
//Overloaded Area
void Area(int radius)
{

cout<<"Circle: Area = "<<(3.14 * radius * radius)<<endl;
}

//Overloaded Circumference
void Circumference(int radius)
{

cout<<"Circle: Circumference = "<<(2 * 3.14 * radius)<<endl;
}

private
:
//Nobody should call these methods
void Area(int length, int breadth) {};
void
Circumference(int length, int breadth) {};
};


int
main()
{

Rectangle r;
cout<<"\n\nRectangle Class - Dimensions 3 x 4"<<endl;
r.Area(3, 4);
r.Circumference(3, 4);

Square s;
cout<<"\n\nSquare Class - Dimensions 3 x 3"<<endl;
s.Area(3);
Shape *s1 = &s; //possible to access derived class through base
s1->Area(3,3);
s.Circumference(3);

Circle c;
cout<<"\n\nCircle Class - Radius is 3"<<endl;
//c.Area(3,3); //- Not Possible as its private in Circle
c.Area(3);
//Shape *c1 = &c; // not possible because conversion from 'Circle *'
// to 'Shape *' exists, but is inaccessible
//c.Circumference(3,3); //- Not Possible as its private in Circle
c.Circumference(3);
return
0;
}




The output of the program is as follows:

Properties of Pure Virtual Functions

In the article Properties
of Virtual Functions
, we discussed about two properties of virtual
functions in detail. In this article we’ll be discussing about some properties
of Pure
Virtual Functions.


Property #1: We know that a
base class can’t define a pure virtual function and at the same time its
derived class must define it. But what if the derived class is used as base
for deriving yet another class; is this possible?


Yes, it is, as is obvious from the following program:



#include <iostream.h>

// base class
class base
{
public:
// pure virtual function
// declaration
virtual void func() = 0;
};

// derived class
class derived1 : public base
{
public:
// must define
void func()
{
cout<<"Derived1's func()\n";
}
};

// derived from class derived1
class derived2 : public derived1
{
public:
void func()
{
cout<<"Derived2's func()\n";
}
};

// main
void main()
{
derived1 d1;
derived2 d2;

d1.func();
d2.func();
}


Hence strictly speaking, a pure virtual function cannot be declared and defined
in the same class.


Property #2: While it’s
necessary for a derived class to override a pure virtual function but if we
derive yet another class from that derived class then it’s not necessary
for the newly derived class to override that function.


So that means, if we have a hierarchy of derived classes then a pure virtual
function must be overridden at least once.


It is clear from the following program:



#include <iostream.h>

// base class
class base
{
public:
// pure virtual function
// declaration
virtual void func() = 0;
};

// derived class
class derived1 : public base
{
public:
// must define
void func()
{
cout<<"Derived1's func()\n";
}
};

// derived from class derived1
class derived2 : public derived1
{
public:
// may not override the
// pure virtual function
};

// main
void main()
{
derived1 d1;
derived2 d2;

d1.func();

// derived1's function will
// be called
d2.func();
}


Property #3: We know that we
can’t declare objects of Abstract
Classes
but since C++ offers very powerful Polymorphism
capability, we can have their pointer (as well as references).


It is clear from the following program:



#include <iostream.h>

// base class
class base
{
public:
// pure virtual function
// declaration
virtual void func() = 0;
};

// derived class
class derived1 : public base
{
public:
// must define
void func()
{
cout<<"Derived1's func()\n";
}
};

// derived from class derived1
class derived2 : public derived1
{
public:
void func()
{
cout<<"Derived2's func()\n";
}
};

// main
void main()
{
// although objects of abstract classes
// cannot be declared but we can have
// their pointers
base *bptr;

derived1 d1;
derived2 d2;

// point to derived1 's object
bptr=&d1;

// derived1's func will be called
bptr->func();

// point to derived2's object
bptr=&d2;

// derived2's func will be called
// same interface is used
// but different function
// is called
bptr->func();
}


Related Articles:


Practical Example of Using Virtual Functions

From the past few articles we have been discussing about virtual functions
but we are yet to observe any of its practical use, this article would do that!


In this article we are going to show you a very simple program that illustrates
the practical use of virtual functions.


Please read the code carefully!



// Practical example of
// when virtual functions are
// used
#include <iostream.h>

class area
{
protected:
int mag;
double a;

public:
area(int x){mag=x;}
double get_area(){return a;}

// pure virtual function
virtual void compute()=0;
// it is made pure as
// it couldn't have any meaningful
// definition since area can only
// be defined w.r.t something specific
};

class circle_area : public area
{
public:
circle_area(int x) : area(x){}

// now that we are referring
// to area w.r.t a circle so
// it is natural that we define
// it
void compute()
{
a=(mag*mag)*3.14;
}
};

class square_area : public area
{
public:
square_area(int x) : area(x){}

// same for this!
void compute()
{
a=mag*mag;
}
};

void main()
{
square_area sa(10);
circle_area ca(20);

sa.compute();
ca.compute();

cout<<"Area of square: "<<sa.get_area();
cout<<endl;
cout<<"Area of cirlce: "<<ca.get_area();
}


Related Articles:


Pure Virtual Functions

From the previous article Properties
of Virtual Functions
, we know that a virtual function may or may not
be overridden in the derived lasses. It means, it is not necessary for a derived
class to override a virtual function.


But there are times when a base class is not able to define anything meaningful
for the virtual function in that case every derived class must provide its own
definition of the that function. To force this type of overriding you use the
following general form to declare a virtual function:



virtual ret-type func-name(arg-list)=0;


This type of virtual function is known as Pure Virtual Function.


There are two major differences between a virtual and a pure virtual function,
these are below:




  • There CAN’T be a definition of the pure virtual function in the base
    class.




  • There MUST be a definition of the pure virtual function in the derived
    class.




By making a virtual function ‘Pure’, it becomes necessary for the
derived classes to override it, further since the base class can’t define
a pure virtual function, we can’t have objects of that class. These types
of incomplete classes (having one or more pure virtual function) are known as
Abstract Classes and are used extensively.


The following program illustrates this:



// Pure Virtual Functions
#include <iostream.h>

// base class
class base
{
public:
// pure virtaul function
// declaration
virtual void func() = 0;
// can't define
};

// derived class
class derived : public base
{
public:
// must define
void func()
{
cout<<"Derived1's func()\n";
}
};

// main
void main()
{
// --CODE: base b
// won't work because we
// can't have objects of
// absract classes
derived d1;

d1.func();
}


Related Articles:


Properties of Virtual Functions

From the previous two articles Introduction
to Virtual Functions
and Virtual
Functions and Run-time Polymorphism
, we have been discussing about
Virtual Functions.


In this article we’ll be discussing about two important properties of
Virtual Functions.


As properties can be better understood by examples, we’ll be using them
more rather than text and definitions that could confuse you.


Property #1:



// Properties of virtual functions
#include <iostream.h>

// base class
class base
{
public:
virtual void func()
{
cout<<"Base's func()\n";
}
};

// derived class
class derived1:public base
{
public:
// this is a virtual function
void func()
{
cout<<"Derived1's func()\n";
}
};

// derived from another
// derived class
class derived2:public derived1
{
public:
// still virtual
void func()
{
cout<<"Derived2's func()\n";
}
};

// main
void main()
{
base b;
derived1 d1;
derived2 d2;

b.func();
d1.func();
d2.func();
}


OUTPUT:

Base's func()
Derived1's func()
Derived2's func()

The code above illustrates that when a class is derived from another derived
class (which has inherited a virtual function from its base class) then also
the virtual function can be overridden. So, it means that once declared virtual,
a function (no matter how many times inherited in hierarchy) still remains Virtual
and hence can be overridden.


Property #2: This is an extension
of the previous property, as you know that a virtual function remains virtual
no matter how many times it is inherited in a hierarchy, but what if one of
the derived class doesn’t overrides it, what will happen then? The following
code answers this!



// Properties of virtual functions
#include <iostream.h>

// base class
class base
{
public:
virtual void func()
{
cout<<"Base's func()\n";
}
};

// derived class
class derived1:public base
{
public:
// this is a virtual function
void func()
{
cout<<"Derived1's func()\n";
}
};

// derived from another
// derived class
class derived2:public derived1
{
public:
// no overriding
};

// another derived class
class derived3:public derived2
{
public:
// can still be overridden
void func()
{
cout<<"Derived3's func()\n";
}
};

// main
void main()
{
base b;
derived1 d1;
derived2 d2;
derived3 d3;

b.func();
d1.func();

// will call the function overridden
// by its base class because it didn't
// override the function
d2.func();

d3.func();
}


OUTPUT:

Base's func()
Derived1's func()
Derived1's func()
Derived3's func()

The above code is pretty much self-explanatory so I don’t think it needs
further explanations.


Related Articles:


Virtual Functions and Run-time Polymorphism

Before beginning this I would like to tell you one thing through the following
program:



// Virtual Functions and
// Run-time Polymorphism
#include <iostream.h>

// base class
class base
{
public:
int a;
};

// derived class
class derived:public base
{
public:
int b;
};

// main
void main()
{
base b;
derived d;

// base class pointer
base *bptr;

// pointer pointing
// to base's object
bptr=&b;

bptr->a=10;

// pointer pointing
// to derived's object
bptr=&d;

// still is able to access
// the members of the base
// class
bptr->a=100;
}


The property above combined with virtual function can be used to achieve a
very special and powerful feature, known as run-time polymorphism.


We had discussed about What
is Polymorphism
before so we wont be discussing it here.


The program below illustrates how virtual functions can be used to achieve
run-time polymorphism.


Please read the code carefully so that you understand how it’s working.



// Using Virtual functions to
// achieve run-time Polymorphism
#include <iostream.h>

// base class
class base
{
public:
virtual void func()
{
cout<<"Base's func()\n";
}
};

// derived class
class derived:public base
{
public:
void func()
{
cout<<"Derived's func()\n";
}
};

// main
void main()
{
int ch=0;

base b;
derived d;

// base class pointer
base *bptr;

while(ch!=3)
{
cout<<"1> Call Base's func\n";
cout<<"2> Call Derived's func\n";
cout<<"3> Quit\n";

cin>>ch;

switch(ch)
{
case 1:
// point to base's object
bptr=&b;
break;

case 2:
// point tp derived's object
bptr=&d;
break;

default:
bptr=&b;
}

// call whichever function
// user has chosen to call
bptr->func();
}
}


Related Articles:


Introduction to Virtual Functions

Virtual functions are special member functions of a class which may be re-defined
in the derived classes. It is used to give specific meaning to the base class
member function with respect to the derive class.


Virtual functions can be thought of as a function name reserved in the bas
class which may be re-defined in the derived classes as per the need so that
every derived class has the same function that performs specific (as redefined
in the derived class) action.


Let’s now have a look at a simple program to show virtual functions inaction:



// Virtual functions
#include <iostream.h>

// base class
class base
{
public:
// precede the function name
// with the 'virtual' keyword
// to make it a virtual function
virtual void func()
{
cout<<"Base's func()\n";
}
};

// derived class
class derived:public base
{
public:
// redefinition of the
// function
void func()
{
cout<<"Derived's func()\n";
}
};

// main
void main()
{
base b;
derived d;

// notice that both are calling
// the same function but different
// functions gets called as per
// the class to which the object
// belongs to
b.func();
d.func();
}


OUTPUT:


  Base's func()
Derived's func()


The redefinition of the virtual function in the derived class is known
as overriding





As you can see there is nothing confusing, the virtual function is a general
member function and is defined as such, only difference being that it’s
preceded by the virtual keyword that gives it the special property.


NOTE: By redefining a virtual function, all its previous meaning (as was defined
in the base class) is lost.


As in the example program the base class defines the virtual function to print
“Base's func()” and the derived class overrides it to print “Derived's
func()”. So when we call the overridden function it only prints what was
defined in the redefinition hence the original meaning of the function is lost.


Related Articles:


Using Virtual Base Classes to Avoid Ambiguity

Let’s start this with the following example program:



// this program contains errors
#include<iostream.h>

// base class
class base
{
public:
int a;
};

// derived class (1)
class derived1:public base
{
public:
int b;
};

// derived class (2)
class derived2:public base
{
public:
int c;
};

// derived class (3)
class derived3:public derived1, public derived2
{
public:
int d;
};

// main
void main()
{
derived3 ob;

// this is ambiguous
// since two copies of
// base is present in
// the class derived3
// one from derived1 &
// the other from derived2
ob.a=10;
}


The program above contains an error (as stated) in the following line:


ob.a=10;


Since the base class is inherited by the two classes (derived1 and derived2),
which are again inherited (both together) by another class derived3, there are
two copies of the base class (and hence two copies of variable ‘a’
too).


Therefore when we refer to the variable ‘a’ with respect to the
derived3 class then as there are two copies of it, it becomes ambiguous or confusing
for the compiler to select one from the two and hence it is reported as an ERROR.


This is very common error which creeps in when you write long and complex program
consisting of classes some of which are hierarchically inherited.


So how can we prevent this from happening?


Actually, we can prevent this by using the scope resolution operator but this
is not a permanent solution besides having other flaws. Then what else can we
do?


Yeah, you guessed it right; Virtual Base Class is he answer.


Now, have a look at the same program with slight modification (as to apply
the virtual base class method), now it’s perfectly all right!



// Virtual base classes
#include<iostream.h>

// base class
class base
{
public:
int a;
};

// derived class (1)
// notice the use of virtual keyword
class derived1:virtual public base
{
public:
int b;
};

// derived class (2)
// notice the use of virtual keyword
class derived2:virtual public base
{
public:
int c;
};

// derived class (3)
class derived3:public derived1, public derived2
{
public:
int d;
};

// main
void main()
{
derived3 ob;

// now it's O. K.
ob.a=10;
}


As you can see, we’re using virtual keyword to derive the classes (derived1
and derived2) from the base class.


This prevents other inheriting classes (which inherits more than one such derived
classes) to have only one copy of the base class and hence ruling out chances
of ambiguity.


Please note that the derived classes (derived1 and derived2 individually) still
contains one-one copy of base class, it is only when they are inherited is the
virtual nature comes into action.


We conclude this article with the following example program to illustrate all
that we have discussed so far in this article.



// Virtual base classes
#include<iostream.h>

// base class
class base
{
public:
int a;
};

// derived class (1)
// notice the use of virtual keyword
class derived1:virtual public base
{
public:
int b;
};

// derived class (2)
// notice the use of virtual keyword
class derived2:virtual public base
{
public:
int c;
};

// derived class (3)
class derived3:public derived1, public derived2
{
public:
int d;
};

// main
void main()
{
derived1 ob1;
derived2 ob2;
derived3 ob3;

// derived classes still
// contain one-one copy
// of the base class
ob1.a=10;
ob2.a=20;

// but the class derived
// form the classes of
// the above two objects
// contains only one copy
// of the base class
ob3.a=100;
}


Related Articles:


Problems Related to Class and Inheritance

To make our ongoing discussion on Inheritance a little more interesting, I
have listed some problems or questions here. They all are related to Classes
in general and Inheritance in particular.


Problem #1: This program contains
some error(s), can you spot which line(s) contains error(s)?



1 // Problems No.1
2 // Related to Inheritance
3 #include<iostream.h>
4
5 // base class
6 class base
7 {
8 int a;
9
10 public:
11 void seta(int num){a=num;}
12 };
13
14 // derived class
15 class derived:public base
16 {
17 int b;
18
19 public:
20 void setb(int num){b=num;}
21
22 void show()
23 {
24 cout<<a<<"\n"<<b;
25 }
26 };
27
28 // main
29 void main()
30 {
31 base b;
32 derived d;
33
34 b.seta(10);
35 d.setb(100);
36
37 d.show();
38 }


Problem #2:
This program contains some error(s), can you spot which line(s) contains error(s)?



1 // Problems No.2
2 // Related to Inheritance
3 #include<iostream.h>
4
5 // base class
6 class base
7 {
8 protected:
9 int a;
10
11 public:
12 void seta(int num){a=num;}
13 };
14
15 // derived class
16 class derived:protected base
17 {
18 protected:
19 int b;
20
21 public:
22 void setb(int num){b=num;}
23 void show()
24 {
25 cout<<a<<"\n"<<b;
26 }
27 };
28
29 // main
30 void main()
31 {
32 base b;
33 derived d;
34
35 b.seta(10);
36 d.setb(20);
37
38 d.show();
39
40 b.a=5;
41 d.b=10;
42
43 d.show();
44 }


Problem #3: This program contains
some error(s), can you spot which line(s) contains error(s)?



1 // Problems No.2
2 // Related to Inheritance
3 #include<iostream.h>
4
5 // base class (1)
6 class base1
7 {
8 protected:
9 int a;
10 };
11
12 // base class (2) derived from
13 // base1
14 class base2:private base1
15 {
16 protected:
17 int b;
18 };
19
20 // derived from base2
21 class derived:public base2
22 {
23 public:
24 void set(int num1,int num2)
25 {
26 a=num1;b=num2;
27 }
28
29 void show()
30 {
31 cout<<a<<"\n"<<b;
32 }
33 };
34
35 void main()
36 {
37 derived d;
38 d.set(10,20);
39
40 d.show();
41 }


ANSWERS:




  1. Line No. 24




  2. Line No. 40 and 41



  3. Line No. 26 and 31


Related Articles:


Parameterized Constructors of Derived Classes

In the previous article Constructors
and Destructors of Derived Classes
, we’re discussing about the
calling conventions of Constructors and Destructor functions of derived classes
whose base class also had them. There was one thing special about those constructors;
none of them were taking arguments.


If only the derived’s constructor takes parameters then also its O. K.
but what if both the base and derived class contains parameterized constructors
(as is obvious from the code below).



// this code contains ERRORS

// base class
class base
{
int a;

public:
base(int n)
{
//...
}
};

// derived class
class derived:public base
{
int b;

public:
derived(int m)
{
//...
}
};

//main
void main()
{
base b(10); //ok

derived d(10); // ERROR!!
// base's constructor
// will also be called and
// it needs parameters too !!
}



How’d you pass arguments to the base class constructor?


To answer this, we need to introduce Expanded from of Constructor Declaration
(of the derived class).



derived-constructor (arg): base1 (arg),
base2 (arg),
...
baseN (arg)
{
...
...
}


Here base1, base2 etc. are constructor functions of base classes, which the
derived class inherits.


Let’s have a look at an example program to understand this declaration:



// this code is ok

// base class
class base
{
int a;

public:
base(int n){a=n;}
};

// derived class
class derived:public base
{
int b;

public:
// since this class is derived
// from only one class 'base'
// therefore only one constructor
// is listed
derived(int m1,int m2):base(m2)
{b=m1;}
};

// main
void main()
{
base b(10); //ok

derived d(10,100); //ok
}




One thing to note here is, the argument which is to be passed to the base’s
constructor should be declared and accepted from the derived class constructor,
as in the line


derived(int m1,int m2):base(m2)
{b=m1;}


Here derived’s constructor is only using the parameter m1 but is accepting
another parameter m2 which is to be passed along to the constructor of the base
class.


Let us have a look at another example program which will clear all the confusions.
Keep reading the comments!



#include<iostream.h>

// base class (1)
class base1
{
protected:
int a;

public:
base1(int p1){a=p1;}
};

//base class (2)

class base2
{
protected:
int b;

public:
base2(int p2){b=p2;}
};

// derived class (1)

class derived1:public base1
{
protected:
int c;

public:
derived1(int p3,int p4):base1(p4)
{c=p3;}

void show(){cout<<a<<"\n"<<c;}
};

//derived class (2)

class derived2:public base1, public base2
{
public:
// this class inherits two base classes

// therefore we are using two base
// class constructors in the declaration
derived2(int p5,int p6):base1(p5),
base2(p6)
{
// empty


// used only to call the base's
// constructors with the passed
// arguments

// derived class constructor may not
// use any arguments passed to it
}

void show(){cout<<a<<"\n"<<b;;}
};

// main

void main()
{
derived1 d1(10,20);
derived2 d2(100,200);

d1.show();
cout<<endl;
d2.show();
}



Related Articles:


Constructors and Destructors of Derived Classes

Classes can have Constructors and/or Destructors and Derived Classes are no
different.


Situation remains understandable until both the base and its derived class
have Constructors and/or Destructors. Since the derived class contains more
than one Constructors and/or Destructors, it becomes confusing which one will
be called when.


This is because when an object the inherited class is constructed both the
constructors (base’s and its own) should be invoked and same applies when
it gets destructed.


This article will clear all this!


Consider the following example program:



// -- INHERITANCE --
// Constructors, Destructors
// and Inheritance
#include<iostream.h>

// base class
class base
{
public:
base(){cout<<"Constructing Base\n";}
~base(){cout<<"Destructing Base\n";}
};

// derived class
class derived:public base
{
public:
derived(){cout<<"Constructing Derived\n";}
~derived(){cout<<"Destructing Derived\n";}
};

void main(void)
{
derived obj;

// do nothing else, only
// construct and destruct
// the inherited class object
}

OUTPUT:


  Constructing Base
Constructing Derived
Destructing Derived
Destructing Base
Press any key to continue


So here is the general rule:



Constructors are called in the order of derivation and Destructors in
the reverse order.



One more example will clear the confusions, if any.:



// -- INHERITANCE --
// Constructors, Destructors
// and Inheritance
#include<iostream.h>

// base class (1)
class base
{
public:
base(){cout<<"Constructing Base\n";}
~base(){cout<<"Destructing Base\n";}
};

// derived class
// derived form 'base'
class derived1:public base
{
public:
derived1(){cout<<"Constructing Derived1\n";}
~derived1(){cout<<"Destructing Derived1\n";}
};

// derived from a derived class
// 'derived1'
class derived2:public derived1
{
public:
derived2(){cout<<"Constructing Derived2\n";}
~derived2(){cout<<"Destructing Derived2\n";}
};

void main(void)
{
derived2 obj;

// do nothing else, only
// construct and destruct
// the inherited class object
}

OUTPUT:


  Constructing Base
Constructing Derived1
Constructing Derived2
Destructing Derived2
Destructing Derived1
Destructing Base
Press any key to continue

Related Articles:


Inheriting from Multiple Base Classes

In the past articles we saw how we can make a class inherit from another class.
This way we could have a new class with features of the base class without explicitly
defining them. But what if, we want to have a new class with features form more
than one class. In other words, Is it possible for a derived class to inherit
multiple base classes (two or more).


Yes it’s possible!


The general from for deriving a class from multiple classes is:



class
derived-class:access-specifier base1,access-specifier base2...
{
...
...
...
};


The following example program illustrates multiple inheritance practically:



// -- INHERITANCE --
// Program to illustrate multiple
// inheritance
#include<iostream.h>

// base class (1)
class base1
{
protected:
int a;

public:
void showa(){cout<<a<<"\n";}
};

// base class (2)
class base2
{
protected:
int b;

public:
void showb(){cout<<b<<"\n";}
};

// derived class
// inherits both base1 and base2
// NOTE: Both the base class have
// access-specifier
class derived:public base1,public base2
{
protected:
int c;

public:
void set(int n1,int n2,int n3)
{
a=n1;b=n2;c=n3;
}

void show()
{
cout<<a<<"\n"<<b<<"\n"<<c<<"\n";
}
};

void main(void)
{
derived d;

d.set(10,20,30);

// access base's members
d.showa();
d.showb();


// access derived's member
d.show();
}


Related Articles:


Deriving a Class from another Derived Class

Many of the peoples think that deriving a class from other derived classes
is a confusing thing, that’s why I have written this article to let them
know that deriving such classes is no different. To the compiler it doesn’t
matter whether the class from which a new class is derived is itself derived
or not.


The example program below illustrates this:



// -- INHERITANCE --
// Example program to illustrate
// the derivation of a class
// from another derived class
#include<iostream.h>

// base class
class one
{
int a;

public:
void setone(int num){a=num;}
int getone(){return a;}
};

// derived from base class 'one'
class two:public one
{
int b;

public:
void settwo(int num){b=num;}
int gettwo(){return b;}
};

// derived from derived class
// 'two'
class three:public two
{
int c;

public:
void setthree(int num){c=num;}
int getthree(){return c;}
};

void main(void)
{
// declare objects
one o1;
two o2;
three o3;

// set values
o1.setone(1);

o2.setone(10);
o2.settwo(20);

o3.setone(100);
o3.settwo(200);
o3.setthree(300);

// display values
cout<<o1.getone()<<endl<<endl;

cout<<o2.getone()<<endl;
cout<<o2.gettwo()<<endl<<endl;

cout<<o3.getthree()<<endl;
cout<<o3.getthree()<<endl;
cout<<o3.getthree()<<endl<<endl;
}


Related Articles:


Protected Members of a Class

In the previous article Defining
Base Class Acess (Inheritance)
we noticed that when we derive one class
from a base class then no matter which base class access-specifier we use, the
members of the derived class doesn’t have access to the private members
of the base class.


But what if we want certain members of the base class to be private to the
class and at the same time accessible to the members of the derived class? Is
there any way of doing it?


Yes, it is possible, by declaring those members as protected members of the
base class.


The following example will show you how:



// ----------------------------
// -- THIS PROGRAM WON'T RUN --
// ----------------------------
// THIS PROGRAM IS DESIGNED TO
// HAVE ERRORS
#include<iostream.h>

// base class
class base
{
int a;

protected:
int b;

public:
int c;
};

// 'derived' class is
// inheriting 'base'
// publicly
class derived:public base
{
int d;

public:
void func()
{
cout<<a; //ERROR
// cannot access private
// members of the base class

cout<<b;

cout<<c;
}
};

void main(void)
{
base b;
derived d;

d.func();// CORRECT

cout<<d.b; // ERROR
// cannot access protected
// members

cout<<d.c; //CORRECT
}


Hence we conclude that protected keyword can be used to declare those members
of the class which should be accessible privately to it and at the same time
should be accessible to the members of its derived class.


Related Articles:


Check out this stream