0% found this document useful (0 votes)
23 views

Constructor

Constructors and destructors are special member functions that initialize and destroy objects of a class. Constructors are invoked when objects are created and can initialize member variables, while destructors are invoked when objects are destroyed to release resources. The document discusses the characteristics and types of constructors such as default, parameterized, copy constructors, and destructor functions in C++.

Uploaded by

arpanabharani
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views

Constructor

Constructors and destructors are special member functions that initialize and destroy objects of a class. Constructors are invoked when objects are created and can initialize member variables, while destructors are invoked when objects are destroyed to release resources. The document discusses the characteristics and types of constructors such as default, parameterized, copy constructors, and destructor functions in C++.

Uploaded by

arpanabharani
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 31

-Constructor & Destructor

Constructors and Destructors are special member functions of a class for initializing and
destroying of objects belonging to that class.

C++ provides a well defined mechanism, for initializing an object when it is created, by means
of a constructors; same way when an object is no more needed, C++ defines a way to destroy it
by the means of a destructors.

C++ Constructors
A class constructor is a special member function of a class which is executed whenever new
objects of that class is created.
A constructor have exact same name as the class and it does not have any return type at all, not
even void. Constructors can be very useful for setting initial values for certain member variables.
In the following example Student() )is a constructor of class Student. It has same name as that of
its class and no return type.
Example:
class Student
{
private :
int rollno;
float marks;
public :

Student()
{
rollno = 0;
marks = 0.0;
}

};
In the above example class has a member function with the same name as its class has and it
provides initial values to its data members. Now, whenever an object of the Student type will be
created (declared), the compiler will automatically call the constructor Student::Student() for the
newly created object.
Characteristics of constructors

Following are the characteristics of constructors:

 They should be declared in public section.


 They are invoked automatically when objects are created.
 They do not have return types, not even void and therefore they cannot return values.
 They cannot be inherited.
 They can have default arguments.
Types of Constructor

Default Constructor:-  Default Constructor is also called as empty Constructor which has no
arguments and it  is automatically called when the object of class is created but the name of
Constructor is same as that of the name of class. Default constructor are never declared with the
help of return type. It is mainly used to initialize the values to variables.

Example:

class addition
  {
        int a, b; 
        public addition()   //default contructor
    {
            a = 100;
            b = 175;
    }
PARAMETRIZED CONSTRUCTOR

The constructors that can take arguments are called parameterized constructors. It may be
necessary to initialize the various data elements of different objects with different values when
they are created.This is achieved by passing arguments to the constructor function when the
objects are created. The parameterized Constructor has one or more arguments and same name as
class name but it uses some arguments.The advantage of a parameterized constructor is that each
instance of the class can be initialized to different values.

Example 1:

class paraconstrctor
  {
      public  int a, b;
      public paraconstrctor(int x, int y)  // decalaring Paremetrized Constructor with int x,y
parameter
    {
            a = x;
            b = y;
    }
   }
Example 2:
class student
{
int rn, total ;
public student (int x, int y)
{
rn = x ; total = y ;
}
};
When the object is created, we must supply arguments to the constructor function. This can be done in two
ways:
 By calling the function explicitly
 By calling the function implicitly
The first call is implemented as follows :
student S1 = student ( 1, 70 ) ;

The second call is implemented as follows :


student S1 ( 1, 70 ) ;

The second method is used very often as it is shorter.

DEFAULT CONSTRUCTOR PARAMETRIZED CONSTRUCTOR

It is useful to initialize all objects with same It is useful to initialize each object with
data. different data.

It does not have any parameters. It will have one or more parameters.

When data is not passed at the time of creating When data is passed at the time of creating an
an object, default constructor is called. object, parameterized constructor is called.

Copy Constructor
A copy constructor takes a reference to an object of the same class as itself as an argument.
Consider the following program segment:
Example
class student

{
int rn, total ;
public :
student (int x, int y )
{
rn = x ; total = y ;
}
student (Student & i )
{
rn = i. rn ;
total = i. total ;
}
};
 The above program has both parameterized and copy constructor.
 The statement student S1 ( 1, 75 ) ; calls the parameterized constructor and assigns 1 to rn
and 75 to total.
 The statement student S2 (S1) ; uses copy constructor and initializes an object S2 from
another object S1. Another form of the statement is student S2 = S1 ;
 The process of initialization through a copy constructor is known as copy initialization.

Note that the statement:


S2 = S1 ; does not invoke the copy constructor. However, it simply assigns the value of S1 to S2,
member by member.

Example 2:
#include< iostream>
class code
{
int id;
public:
code()
{ }
code(int a)
{
id=a;
}
code(code &x)
{
id=x.id;
}
void display()
{
cout<< id;
}
};

int main()
{
code A(100);//parameterised constructor called
code B(A); //copy constructor called
code C=A; //copy constructor called
cout<<"\n id of A="; A.display();
cout<<"\n id of B="; B.display();
cout<<"\n id of C="; C.display();
}
Output
id of A=100
id of B=100
id of C=100

Overloading Constructors
Constructors perform a unique service but they constructors are not much different from
other types of functions, and they too can be overloaded. To overload a class’ constructor,
simply declare the various forms it will take. For example, the following program defines
three constructors:

#include<iostream>
#include<conio.h>
class values {
int a, b;
public:
//Constructor wuithout Argument
values ()
{
a = 100;
b = 200;
cout << "\nThis is Constructor";
}
//Constructor with one argument
values (int x)
{
x=y=i
}
//Constructor with two argument
values(int x, int y)
{
a = x;
b = y;
cou
t << "\nThis is Constructor";
}

void Display() {
cout << "\nValues are :" << a << "\t" << b;
}
};

int main() {
values Object1(50)
values Object(30, 40);
values Object2;
Object.Display();
Object2.Display();
Object1.Display();
getch();
return 0;
}
Output
This is Constructor
This is Constructor
Values are :30 40
Values are :100 200
Values are : 50 50
The above program creates three constructors. The first is a parameterless constructor, which
initializes a to 100 and b to 200. This constructor becomes the default constructor, replacing
the default constructor supplied automatically by C++. The second takes one parameter,
assigning its value to both x and y. The third constructor takes two parameters, initializing x
and y individually.
Overloaded constructors are beneficial for several reasons.
 They add flexibility to the classes, allowing an object to be constructed in a variety of
ways.

 They offer convenience to the user of the class by allowing an object to be constructed
in the most natural way for the given task.

 By defining both a default constructor and a parameterized constructor, both initialized


and uninitialized objects are created.

Destructors
A destructor as the name implies, is used to destroy the objects that have been created by a
constructor. A destructor is a member function whose name is same as the class name but
preceded by a tilde(~). For example:
~student() { }

Following are the characteristics of destructors:

 They never takes an argument nor does it return any value.


 They will be invoked implicitly by compiler upon exit from the program or block or
function.
 It is good practice to use destructors in a program since it releases memory for future use.

Example:
#include<iostream>
class Marks
{
public:
int english;
int hindi;
//constructor
Marks() {
cout << "Inside Constructor"<<endl;
cout << "C++ Object created"<<endl;
}
//Destructor
~Marks() {
cout << "Inside Destructor"<<endl;
cout << "C++ Object destructed"<<endl;
}
};
int main( )
{
Marks m1;
Marks m2;
return 0;
}
Output
Inside Constructor
C++ Object created
Inside Constructor
C++ Object created

Inside Destructor
C++ Object destructed
Inside Destructor

C++ Object destructed

Operator Overloading

C++ allows you to specify more than one definition for an operator in the same scope, which is
called operator overloading. An overloaded declaration is a declaration that is declared with the
same name as a previously declared declaration in the same scope, except that both declarations
have different arguments and obviously different definition (implementation).

When you call an overloaded function or operator, the compiler determines the most
appropriate definition to use, by comparing the argument types you have used to call the function
or operator with the parameter types specified in the definitions. The process of selecting the
most appropriate overloaded function or operator is called overload resolution.

Most of the built-in operators available in C++ can be redefined or overloaded. Thus, a
programmer can use operators with user-defined types as well.
Overloaded operators are functions with special names: the keyword "operator" followed by the
symbol for the operator being defined. Like any other function, an overloaded operator has a
return type and a parameter list.

complex operator+(const complex&);

declares the addition operator that can be used to add two complex objects and returns final
complex object. Most overloaded operators may be defined as ordinary non-member functions or
as class member functions. In case we define above function as non-member function of a class
then we would have to pass two arguments for each operand as follows −

complex operator+(const complex &, const complex &);

Following is the example to show the concept of operator over loading using a member function.
Here an object is passed as an argument whose properties will be accessed using this object, the
object which will call this operator can be accessed using this operator as explained below −

Things to remember

1. Operator overloading allows you to redefine the way operator works for user-defined
types only (objects, structures). It cannot be used for built-in types (int, float, char etc.).
2. Two operators = and & are already overloaded by default in C++. For example: To copy
objects of same class, you can directly use = operator. You do not need to create an
operator function.
3. Operator overloading cannot change the precedence and associatively of operators.
However, if you want to change the order of evaluation, parenthesis should be used.
4. There are 4 operators that cannot be overloaded in C++. They are :: (scope resolution), .
(member selection), .* (member selection through pointer to function) and ?: (ternary
operator).

Overloadable/Non-overloadableOperators

Following is the list of operators which can be overloaded −

+ - * / % ^
& | ~ ! , =
< > <= >= ++ --
<< >> == != && ||
+= -= /= %= ^= &=
|= *= <<= >>= [] ()
-> ->* new new [] delete delete []

Following is the list of operators, which can not be overloaded −


:: .* . ?:

Overloading Unary Operator

The unary operators operate on a single operand and following are the examples of Unary
operators −

 The increment (++) and decrement (--) operators.


 The unary minus (-) operator.
 The logical not (!) operator.

The unary operators operate on the object for which they were called and normally, this operator
appears on the left side of the object, as in !obj, -obj, and ++obj but sometime they can be used
as postfix as well like obj++ or obj--.

The following example shows how minus (-) operator can be overloaded for prefix as well as
postfix usage.

Example:

#include <iostream>
class Distance {
private:
int feet;
int inches;
public:
Distance()
{
feet = 0;
inches = 0;
}
Distance(int f, int i)
{
feet = f;
inches = i;
}

// method to display distance


void display ()
{
cout << "Feet: " << feet << " Inches:" << inches <<endl;
}

// overloaded minus (-) operator


Distance operator- ()
{
feet = -feet;
inches = -inches;
return Distance(feet, inches);
}
};

int main()
{
Distance D1(11, 10), D2(-5, 11);

-D1; // apply negation


D1.displayDistance(); // display D1

-D2; // apply negation


D2.displayDistance(); // display D2

return 0;
}

When the above code is compiled and executed, it produces the following result −

Feet: -11 Inches:-10


Feet: 5 Inches:-11

Similar concept can be applied to overload Logical Not Operators (!).

Overloading Binary operators

The binary operators take two arguments and following are the examples of Binary operators.
The binary operators like addition (+) operator, subtraction (-) operator and division (/) operator
are frequently used.

Following example explains how addition (+) operator can be overloaded. Similarly subtraction
(-) and division (/) operators can be overloaded.

Example:
#include<iostream.h>
#include<conio.h>
class complex {
int x, y;
public:
void getvalue() {
cout << "Enter the value of Complex Numbers x,y:";
cin >> x>>y;
}
complex operator+(complex ob) {
complex c;
c.x = x + ob.x;
c.y = y + ob.y;
return (c);
}

complex operator-(complex ob) {


complex c;
c.x = x - ob.x;
c.y = y - ob.y;
return (c);
}

void display() {
cout << x << "+" << y << "i" << "\n";
}
};

void main() {
clrscr();
complex obj1, obj2, result, result1;

obj1.getvalue();
obj2.getvalue();

result = obj1 + obj2;


result1 = obj1 - obj2;

cout << "Input Values:\n";


obj1.display();
obj2.display();

cout << "Result:";


result.display();
result1.display();

getch();
}

Output:

Enter the value of Complex Numbers x, y


6 7
Enter the value of Complex Numbers a, b
4 3
Input Values
6 + 7i
4 + 3i
Result
10 + 10i
2 + 4i

Inheritance

One of the most important concepts in object-oriented programming is that of inheritance.


Inheritance allows a class to be defined in terms of another class, which makes it easier to create
and maintain an application. This also provides an opportunity to reuse the code functionality
and fast implementation time.

When creating a class, instead of writing completely new data members and member functions,
the programmer can designate that the new class should inherit the members of an existing class.
This existing class is called the base class, and the new class is referred to as the derived class.

The idea of inheritance implements the is a relationship. For example, mammal IS-A animal, dog
IS-A mammal hence dog IS-A animal as well and so on.

Basic Syntax of Inheritance

class derived-class: access-specifier base-class

While defining a derived-class like this, the base-class must be already defined or at least
declared before the derived-class declaration.

Access specifier is used to specify, the mode in which the properties of base-class will be
inherited into derived-class, public, privtate or protected.

Example of Inheritance
class Animal
{ public:
int legs = 4;
};

class Dog : public Animal


{ public:
int tail = 1;
};

int main()
{
Dog d;
cout << d.legs;
cout << d.tail;
}

Output :

41

Base and Derived Classes

A class can be derived from more than one classes, which means it can inherit data and functions
from multiple base classes. To define a derived class, we use a class derivation list to specify the
base class. Consider a base class Shape and its derived classes Rectangle and Triangle as
follows −

class Shape
{
protected:
float breadth, length;
public:
void set_data (float x, float y)
{
breadth = x;
length = y;
}
};

class Rectangle: public Shape


{
public:
float area ()
{
return (breadth * length);
}
};

class Triangle: public Shape


{
public:
float area ()
{
return (breadth * length / 2);
}
};

int main ()
{
Rectangle rect;
Triangle tri;
rect.set_data (6,5);
tri.set_data (4,5);
cout << rect.area() << endl;
cout << tri.area() << endl;
return 0;
}

Output :

30
10

The object of the class Rectangle contains : breadth, length inherited from Shape becomes the
protected member of Rectangle. set_data() inherited from Shape becomes the public member of
Rectangle area is Rectangle’s own public member
 
The object of the class Triangle contains : breadth, length inherited from Shape becomes the
protected member of Triangle. set_data() inherited from Shape becomes the public member of
Triangle area is Triangle’s own public member

set_data () and area() are public members of derived class and can be accessed from outside class
i.e. from main().

A major benefit of inheritance is that once you have created a base class that defines the
attributes common to a set of objects, it can be used to create any number of more specific
derived classes. Each derived class can precisely adapt its own classification.

Modes of Inheritance

 Public mode: In this mode a sub class is derived from a public base class. Then the
public member of the base class will become public in the derived class and protected
members of the base class will become protected in derived class. Private members of the
base class will never get inherited in sub class. All the class members declared under
public will be available to everyone. The data members and member functions declared
public can be accessed by other classes too. The public members of a class can be
accessed from anywhere in the program using the direct member access operator (.) with
the object of that class.

Example:

// C++ program to demonstrate public access modifier


 #include<iostream>
 
// class definition
class triangle
{
    public:
        double base;
double height
         
        double  compute_area()
        {
            return base*height*1/2;
        }
     
};
 
// main function
int main()
{
    triangle obj;
     
    // accessing public datamember outside class
    obj.width = 5;
obj.height = 6

     
    cout << "Width is:" << obj. width << "\n";
cout << "Height is:" << obj. height << "\n";

    cout << "Area is:" << obj.compute_area();


    return 0;
}

Output:

Width is:5
Height is :6
Area is:15

 Protected mode: In this mode a sub class is derived from a protected base class. Then
both public member and protected members of the base class will become protected in
derived class. Private members of the base class will never get inherited in sub class.
 Private mode: In this mode a sub class is derived a Private base class. Then both public
member and protected members of the base class will become Private in derived class.
Private members of the base class will never get inherited in sub class.

Example:
// C++ program to demonstrate private access modifier
 
#include<iostream>
class triangle
{  
    // private data member
    private:
        double width;
double height
         
             
    // public member function   
    public:   
// member function can access private data member width and height
        double  compute_area()
        {              return base*height*1/2;
        }
     
};
 
// main function
int main()
{  
    // creating object of the class
    triangle obj;
     
    // trying to access private data member directly outside the class
    obj.width = 5;
     
    cout << "Area is:" << obj.compute_area();
    return 0;
}

The output of above program will be a compile time error because we are not allowed to
access the private data members of a class directly outside the class.
Output:

In function 'int main()':


11:16: error: 'double triangle::width' is private
double width;
^
31:9: error: within this context
obj.width = 5;

However we can access the private data members of a class indirectly using the public member
functions of the class. Below program explains how to do this:

Example:
// C++ program to demonstrate private access modifier
 
#include<iostream>
class triangle
{  
    // private data member
    private:
        double width;
double height
      
    // public member function   
    public:   
        double  compute_area(double w, double h)
        {   // member function can access private data member radius
            width = w;
             height = h;
            double area = width*height*1/2;
cout << "Width is:" << width << "\n";
cout << "Height is:" << height << "\n";
    cout << "Area is:" << area;
    return 0;
                 
        }
     
};
 int main()
{  
    // creating object of the class
    triangle obj;
    
    // trying to access private data member directly outside the class
    obj.compute_area(5,6);
     
       return 0;
}
Output:
Width is: 5
Height is : 6
Area is: 15

Types of Inheritance in C++

1. Single Inheritance: In single inheritance, a class is allowed to inherit from only one
class. i.e. one sub class is inherited by one base class only.

Syntax:
2. class subclass_name : access_mode base_class
3. {
4. //body of subclass
5. };

Example:
// C++ program to explain Single inheritance
#include<iostream.h>
#include<conio.h>
class student
{
public:
int rollno;
char sname[20];
void getdata()
{
cout<<"Enter RollNo :- \t";
cin>>rollno;
cout<<"Enter Name :- \t";
cin>>sname;
}
};
class marks : public student
{
public:
int sub1,sub2,sub3,tot;
float per;
void getmarks()
{
getdata();
cout<<"Enter Marks of Subject 1 :- \t";
cin>>sub1;
cout<<"Enter Marks of Subject 2 :- \t";
cin>>sub2;
cout<<"Enter Marks of Subject 3 :- \t";
cin>>sub3;
}
void display()
{
getmarks();
cout<<"Roll No\t \t Name \t Subject1 \t Subject 2 \t Subject 3 \t Total \
t Percentage";
cout<<rollno<<"\t"<<sname<<"\t"<<sub1<<"\t"<<sub2<<"\
t"<<sub3<<"\t"<<tot<<"\t"<<per;
}
};
void main()
{
student std;
clrscr();
std.getmarks();
std.display();
getch();
}

Multilevel Inheritance: In this type of inheritance, a derived class is created from another

derived class.
Example 1:
// C++ program to implement
// Multilevel Inheritance
#include <iostream>
// base class
class Vehicle
{
  public:
    Vehicle()
    {
      cout << "This is a Vehicle" << endl;
    }
};
class fourWheeler: public Vehicle
{  public:
    fourWheeler()
    {
      cout<<"Objects with 4 wheels are vehicles"<<endl;
    }
};
// sub class derived from two base classes
class Car: public fourWheeler{
   public:
     car()
     {
       cout<<"Car has 4 Wheels"<<endl;
     }
};
 
// main function
int main()
{  
    //creating object of sub class will invoke the constructor of base classes
    Car obj;
    return 0;
}
Output:
This is a Vehicle
Objects with 4 wheels are vehicles
Car has 4 Wheels

Example 2:
#include<iostream>
class Student{
protected:
int marks;

public:
void accept(){
cout<<" Enter marks";
cin>>marks;

}
};

class Test :public Student{


protected:

int p=0;

public:
void check(){
if(marks>60){
p=1;
}
}
};

class Result :public Test{


public:
void print(){
if(p==1)
cout<<"\n You have passed";
else
cout<<"\n You have not passed";
}
};
int main(){
Result r;
r.accept();
r.check();
r.print();
return 0;
}
Output:
Enter marks 70
You have passed

As you can see there are three different classes that have been used such as the class Student,
class Test and class result. Here the class student is inherited in class test whereas class Test is
inherited in the class Result. The members of class Students can be accessed by the other two
classes. As we have created only one object for result class Result this means that we can access
all members from the other two classes. This is called multilevel inheritance.

Multiple Inheritance: Multiple Inheritance is a feature of C++ where a class can inherit from
more than one classes. i.e one sub class is inherited from more than one base classes.

Syntax:
class subclass_name : access_mode base_class1, access_mode base_class2, ....
{
//body of subclass
};

Here, the number of base classes will be separated by a comma (‘, ‘) and access mode for every
base class must be specified.

Example:
#include<iostream.h>
#include<conio.h>

class student {
protected:
int rollno, sub1, sub2;
public:
void getmarks() {
cout << "Enter the Roll no :";
cin>>rollno;
cout<<"Enter Marks of Subject 1 :- \t";
cin>>sub1;
cout<<"Enter Marks of Subject 2 :- \t";
cin>>sub2;
}
};

class computer {
protected:
int cmarks; // cmarks = computer marks
public:

void getcm() {
cout << "\nEnter the computer marks :";
cin>>cmarks;

}
};

class result : public student, public computer {


int total, avg;
public:

void display() {
total = (sub1 + sub2 + cmarks);
avg = total / 3;
cout << "\n\n\tRoll No : " << rollno << "\n\tTotal : " << total;
cout << "\n\tAverage : " << avg;
}
};

void main() {
clrscr();
result obj;
obj.getmarks();
obj.getcm();
obj.display();
getch();
}
Output
Enter the Roll no: 1000
Enter two marks
75
85
Enter the Computer marks: 80
Roll No: 1000
Total : 240
Average: 80

Hierarchical Inheritance: In this type of inheritance, more than one sub class is inherited from
a single base class. i.e. more than one derived class is created from a single base class.

/*C++ program to show example of hierarchical inheritance to get square and cube of a
number.*/

#include <iostream>
class number
{
    private:
int num;
    public:
void getnumber(void)
{
cout << "Enter an integer number: ";
cin >> num;
}
int returnnumber(void)
{
return num;
}
};

//Base Class 1, to calculate square of a number


class sqr:public number
{
    public:
int getsqr(void)
{
int num,sqr1;
num=returnnumber();
sqr1=num*num;
return sqr1;
}
};

//Base Class 2, to calculate cube of a number


class Cube:public Number
{
    private:

    public:
int getcube(void)
{
int num,cube;
num=returnnumber();
cube=num*num*num;
return cube;
}
};
int main()
{
sqr objs;
cube objc;
int sqr,cube;

objs.getnumber();
sqr1 =objs.getsquare();
cout << "Square of "<< objs.returnNumber() << " is: " << sqr1 << endl;

objc.getnumber();
cube=objc.getcube();
cout << "Cube of "<< objs.returnNumber() << " is: " << cube << endl;

return 0;
}

Output

Enter an integer number: 5


Square of 5 is: 25
Enter an integer number: 10
Cube of 10 is: 1000

Hybrid (Virtual) Inheritance: Hybrid Inheritance is implemented by combining more than one
type of inheritance. For example: Combining Hierarchical inheritance and Multiple Inheritance.

Example:
#include<iostream.h>
#include<conio.h>
class student
{
protected:
int rno;
public:
void getno(int a)
{
rno=a;
}
void putno(void)
{
out<<"Roll no"<<rno<<"\n";
}
};
class test:public student
{
protected:
float marks1,markst2;
public:
void getmark(float x,float y)
{
marks1=x;
marks2=y;
}
void put_marks()
{
cout<<"Marks obtained:"<<"marks1="<<marks1<<"\n"<<"markst2="<<marks2<<"\n";
}
};
class computer
{
protected:
float cmarks;
public:
void getcmarks(float c)
{
cmarks=s;
}
void putcmarks(void)
{
cout<<"Computer:"<<cmarks<<"\n";
 
}
};
 
class result: public test, public computer
{
float total;
public:
void display(void);
};
void result::display(void)
{
total=marks1+marks2+cmarks;
putno();
putmarks();
putcmarks();
cout<<"Total Marks="<<total<<"\n";
}
int main()
{
clrscr();
result stu;
stu.getno(100);
stu.getmark(75.0,85.0);
stu.getcmarks(90.0);
stu.display();
return 0;
}

Output:

Roll no 100
Marks obtained : marks1=75.0
marks2=85.0
Computer=90
Total Marks = 250

C++ Virtual Base Class

Virtual base class is used in situation where a derived have multiple copies of base class.
Consider the following figure:

Example without using virtual base class:

#include<iostream.h>
#include<conio.h>

class ClassX
{
public:
int x;
};

class ClassY : public ClassX


{
public:
int y;
};
class ClassZ : public ClassX
{
public:
int z;
};

class ClassW : public ClassY, public ClassZ


{
public:
int w;
};

void main()
{

ClassW obj;

obj.x = 100; //Statement 1, Error occur


obj.x = 200; //Statement 2, Error occur

obj.y = 200;
obj.z = 300;
obj.w = 400;

cout<< "\n X : "<< obj.x;


cout<< "\n Y : "<< obj.y;
cout<< "\n Z : "<< obj.z;
cout<< "\n W : "<< obj.w;

Output :

X from ClassY : 100


X from ClassZ : 200
Y : 20
Z : 30
W : 40

In the above example, both ClassY & ClassZ inherit ClassX, they both have single copy of
ClassX. However ClassW inherit both ClassY & ClassZ, therefore ClassW have two copies of
ClassX, one from ClassY and another from ClassZ.
Statement 1 and 2 in above example will generate error, bco'z compiler can't differentiate
between two copies of ClassX in ClassW.

To remove multiple copies of ClassX from ClassW, we must inherit ClassX in ClassY and
ClassZ as virtual class.

Example using virtual base class:

#include<iostream.h>
#include<conio.h>

class ClassX
{
public:
int x;
};

class ClassY : virtual public ClassX


{
public:
int y;
};
class ClassZ : virtual public ClassX
{
public:
int z;
};

class ClassW : public ClassY, public ClassZ


{
public:
int w;
};

void main()
{

ClassW obj;

obj.x = 100; //Statement 1


obj.x = 200; //Statement 2

obj.y = 300;
obj.z = 400;
obj.w = 500;

cout<< "\n X : "<< obj.x;


cout<< "\n Y : "<< obj.y;
cout<< "\n Z : "<< obj.z;
cout<< "\n W : "<< obj.w;
}
Output :
A : 200
B : 300
C : 400
D : 500

According to the above example, ClassW have only one copy of ClassX and statement 4 will
overwrite the value of x, given in statement 3.

You might also like