[go: up one dir, main page]

0% found this document useful (0 votes)
34 views38 pages

BCA5

Uploaded by

Asharfali Shaikh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views38 pages

BCA5

Uploaded by

Asharfali Shaikh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

Unit

OBJECTS AND CLASSES

Lesson Structure

5.0 Objective

5.1 Introduction

5.2 Specifying a Class

5.3 Creating Objects

5.4 Accessing Class Members

5.5 Member Functions

5.6 Constructors

5.7 Objects as Function Arguments

5.8 Summary

5.9 Questions

5.10 Suggested Readings

5.0 Objective

After going through this unit you will understand:

 Usage of Classes and Objects in C++


 How class members are accessed
 Usage of Member Functions
 Importance of Constructors
 How objects are passed as function arguments

5.1 Introduction

In C++, the basic building block that results in OOP (Object Oriented Programming) is a Class. A class is a
user-defined type that consists of its own data members and member functions. By creating an instance of the
class we can access and use these data members and member functions. We can say that a class is a blueprint
to create an object. An object is nothing but an instance of a class. No memory is allocated when the class is
defined. However, when an object of that class is created then memory is allocated. When the definition of a
function lies within the definition of a class, then that function is the member function of the class. A member
function can operate on any object of the class of which it is a member. It can access all the members of a
class for that object. A constructor is a special function that initializes every object. Whenever an object is
created, the compiler calls the constructor. After an object is allocated a storage, the constructor initializes
values to the members of the object.

The rest of the unit is organized as follows. Section 5.2 explains how to specify a class. Section 5.3 discusses
how objects are created. Sections 5.4 and 5.5 describe class members and member functions. Section 5.6
describes the usage of constructors. Section 5.7 explains how objects are passed as function arguments.
Section 5.8 gives a brief summary on the unit. Section 5.9 contains some questions for the students to workout.
Section 5.10 shows some suggested readings.

5.2 Specifying a Class

A class is a method of binding data and its related functions together. If needed, data and its related functions
can be hidden from external usage. A new abstract data type is created when a class is defined. This data
type is used like any other built-in data type. Basically, a class specification has two parts:
1. Declaration of the class
2. Defining the class functions
The type and scope of a class are described by its class declaration. The class function definitions explain
the implementation of the class functions.
The basic syntax for class declaration is:
class class-name
{
private:
declaration of variables;
declaration of functions;
public:
declaration of variables;
declaration of functions;
};
The class keyword points towards the creation of an abstract data of type class-name. The class body
comprises of declarations of variables and declarations of functions. Variables and functions are
collectively referred to as class members. They can be categorized as private or public.
Private members of the class can only be accessed from inside the class, whereas public members can be
accessed from outside the class also. All the members of a class are private by default. So, there is no need
to use the keyword private. This feature (data hiding through private declaration) is one of the major features
of OOP.
All the variables that are declared within a class are called its data members, whereas all the functions that
are declared within a class are called its member functions. Private data members and private functions can
be accessed by the member functions of that class only. Nevertheless, public data members and public
functions can also be accessed from outside the class. This has been shown in Figure 5.1 below. When data
and functions are bound together in a single class-type variable, we call it encapsulation.

CLASS

Private area
Data
No entry allowed
Functions

Data Public area

Entry allowed
Functions

Figure 5.1: Data hiding in classes

A general class declaration has the following syntax:


class product
{
int count; // declaration of variables is by default private
float price;
public:
void getdata(int x, float y); // declaration of functions through prototype
void putdata(void);
};
The class product comprises of two data members that are by default private, and two member functions
that have been declared as public. The function getdata() assigns values to the data members and the
function putdata() is used to display those values. The private data members of the class product can only
be accessed by these two member functions that have been declared as public. In other words, any function
which is not a member function of the class product cannot access the data.

5.3 Creating Objects

We should remember that the declaration of product as shown in the previous section, only species what
the objects will contain, but does not define those objects. After declaration of a class, we can construct
object (like variables) of the type by utilizing the name of the class. For instance,

product m; //memory is created for m

creates a object by name m of type product. Here m is like variable and product is like data type. product
is user defined data type. It is very similar to declaration of variable of any data like. For example: int a;
Class variables are referred to as objects in C++. In other words, m is an object of type product. C++ allows
us to declare multiple objects in a single statement. For instance,

product m, n, o;

Note: Object is being created in memory. Then we have answer one obvious question “What is size
of object?” It is like int taken 2 Byte space in memory. Float takes 4 Byte space in memory
and so on. Similarly, object takes memory space which is equal to sum of space taken by all
data members only. Function member does not belong to object rather it is stored in common
place for all the objects of same class.
In the above program, m takes 6 Byte space (2 Byte for count + 4 byte for price). Similarly,
Object n and o also takes 6 Byte each.
We can sizeof operator to find out the memory space. Syntax is:
cout<<”Size of Object m is”<< sizeof(m);

We can declare an object just like we declare a variable of any basic type. The declaration creates memory
space for all the objects declared in the statement. Here we should remember that, like a structure, class
specification only provides a template and no object is allocated any memory space during this period.
Another method of creating objects while a class is being defined, is to place the object names just after the
closing bracket. This has been shown below.

class product
{
……..
……..
……..
} m, n, o;

will create the objects m, n and o of data type product. This method however is rarely followed by
programmers.

5.4 Accessing Class Members

As we have already seen, only a member function of a class can access the private data members of the
class. The function main() can’t contain statements that can directly access count and price. The syntax to
call a member function is as follows:

object-name.function-name (actual-arguments);

For instance, the following function call statement

m.getdata(50,85.7);

is effective and allots the value 50 to count and 85.7 to price of object m through the implementation of
the function getdata().

The following statement displays the values of the data members.

m.putdata();

Here we should note that only an object of a class can invoke the member function of that class. So, the
following statement,

getdata(50,85.7);

is not valid. The statement,

m.count =50;

is also not valid. The variable count has been declared as private. Therefore, it cannot be accessed by using
an object of the class. It can be accessed through a member function of the class.

If a variable is declared as public, it can be accessed directly by an object. But a variable that is private
cannot be accessed directly by an object. The following example explains the statements.

class abc
{
int m;
int n;
public:
int p;
};
………
………
abc z;
z.m = 0; // m is private. Error in statement
z.p = 5; // p is public. Statement is OK
……….
……….

Static Data Members

We can qualify a data member of a class as static. A static member variable possesses the same features as
a static variable of C. There are some special features of a static member variable which have been discussed
below.
 When the first object of its class is created, a static member variable is initialized to zero. No other
initialization is allowed.
 All the objects of the class share only one copy of the static member, which is created for the entire
class.
 It is only visible inside the class, but its lifetime is the entire program.

A static variable is generally used to maintain the values that are common in the entire class. A static data
member, for example, can be used like a counter in which the occurrences of all the objects are recorded.
Program: usage of a static data member.

#include<iostream>
using namespace std;
class product
{
static int number;
int value;
public:
void getdata(int z)
{
value = z;
number ++;
}
void getnumber(void)
{
cout << "count: ";
cout << number << "\n";
}
};
int product :: number;
int main()
{
product m,n,p; //count is initialized to zero
m.getnumber(); // display count
n.getnumber();
p.getnumber();

m.getdata(10); // get data into object m


n.getdata(20); //get data into object n
p.getdata(30); //get data into object p

cout << "After reading the data" << "\n";

m.getnumber(); // display count


n.getnumber();
p.getnumber();
return 0;
}

Output:
count: 0
count: 0
count: 0
After reading the data
count: 3
count: 3
count: 3

The following statement in the program is the definition of the static data member

int product :: number;

We should remember that each static member variable’s type and scope should be defined outside the class
definition. The reason is that static data members are not stored as a part of any object, but are stored
separately. They are known as class variables as they are not associated with any object of the class, but
the class itself.
With the creation of objects the count of the static variable is initialized to zero. Whenever data is read into
an object, this count is incremented. In the above program data is read into the objects three times. So, the
count is also incremented three times. All the three objects share a single copy of count. Hence, all the three
output statements lead to value 3 being displayed. Figure 5.2 shows how objects use a static variable.
Figure 5.2 Sharing of a static data member
As static variables are declared within a class and defined outside the class, they are similar to non-inline
member functions. We can also give some initial value to a variable when a static variable is defined. In
the following definition
For example, the following definition gives count the initial value 15.
int product :: number = 15;

5.5 Member Functions


A member function can be defined at two locations:

1. Outside the definition of class


2. Within the definition of class
It is certain that regardless of the location of function definition, it will perform the same job. So, the code
inside the body of the function should be same in both the situations. Nonetheless, there is a difference in
the way in which the function header is defined.
Outside the Definition of Class
If a member function is declared inside a class, it has to be defined outside the class separately. The
definition must have a function body and a function header. A member function differs from a normal
function as there is a membership ‘identity label’ in the header of the member function. With the help of
this ‘label’ the compiler identifies the class to which the function belongs. The basic syntax for a member
function definition is as follows:

return-type class-name :: function-name (declaration of argument)


{
function body
}
From the above statement the compiler learns that the function function-name belongs to the class class-
name. In other words, the function’s scope is limited to the class-name stated in the header. The symbol ::
is known as the scope resolution operator.

Let us consider getdata() and putdata(), the two member functions that have been discussed above. The
following example explains how member functions are defined.

void product :: getdata(int x, float y)


{
count = x;
price = y;
}
void product :: putdata(void)
{
cout << “Count :” << count << “\n”;
cout << “Price :” << price << “\n”;

The return-type of these functions is void as these functions do not return any value. There are some special
features of member functions that are frequently used in the development of programs. These features are
as follows:
 The same function name can be used in multiple classes. Compiler will use their membership labels
to identify their class.
 The private data of a class can be accessed by the member functions of that class only. However,
friend function is an exception to this rule.
 A member function can be directly called by another member function, without the usage of the
dot operator.

Within the Definition of Class


A member function can also be defined by replacing the function declaration inside the class by the actual
function definition. The following code explains the method.

class product
{
int count;
float price;
public:
void getdata(int x, float y); // a function declaration

// following is an inline function

void putdata(void) // a function definition within class


{
cout << count << “\n”;
cout << price << “\n”;
}
};

A function that is defined within a class is treated like an inline function. All the limitations and restrictions
that are applicable to an inline function can be applied to this function also. Generally, programmers define
small functions inside a class.
Now let us try to understand the program below which implements all the details discussed so far.
Program: defining member functions
#include<iostream>
using namespace std;
class product
{
int count; // by default private
float price; // by default private
public:
void getdata(int x, float y); // prototype declaration defined later

// Function defined within the class

void putdata(void)
{
cout << “Count: ” << count << “\n”;
cout << “Price: ” << price << “\n”;
}
};

//…………………..Member Function Definition………………….

void product :: getdata(int x, float y) // membership label is used


{
count = x; // private variables are directly used
price = y;
}
//……………………..Main Program………………………..
int main()
{
product m; // object m is created
cout << “\nobject m” << “\n”;
m.getdata(100, 299.95); // call member function
m.putdata(); // call member function
product n; // another object is created
cout << “\nobject n” << “\n”;
n.getdata(200, 175.50);
n.putdata();
return 0;
}

Output:

object m
number: 100
cost: 299.95

object n
number: 200
cost: 175.5

This program contains a class product. The class comprises of two public functions and two private
variables. The member function getdata() that is defined outside the class provides values to these
variables. The statement,

count = x;

in the definition of the function getdata(). It exhibits that a member function of a class can directly access
its private data members.

The member function putdata() that is defined inside the class is treated as an inline function. The function
is used to display the values of the private variables count and price.

Making an Outside Function Inline

One of the major characteristics of Object Oriented Programming is isolating the implementation details
from the class definition. Defining member functions outside a class is therefore a good practice.
We can make a member function inline even if it is defined outside the class. For this we just have to use
the qualifier inline in the header of the function definition. The example below shows the syntax for the
same.

class product
{
…………
…………
public:
void getdata(int x, float y); // function declaration
};
inline void product :: getdata(int x, float y) // function definition outside the class
{
count = x;
price = y;
}
Nesting of Member Functions

If we want to call a member function, we can also do so by using its name within a separate member function
of the same class. It is called nesting of member functions which is shown in program below.
Program: nesting of member functions
#include<iostream>
using namespace std;
class value
{
int a,b;
public:
void enter(void);
void output(void);
int biggest(void);
};
int value :: biggest (void)
{
if(a >= b)
return (a);
else
return (b);
}
void value :: enter(void)
{
cout << “ Enter the values of a and b” << “\n”;
cin >> a >> b;
}
void value :: output(void)
{
cout << “Biggest value is ” << biggest() << “\n”; // calling member function
}
int main()
{
value M;
M.enter();
M.output();
return 0;
}

Output:

Enter the values of a and b


32
67
Biggest value is 67

Private Member Functions

Normally all the member functions are public and all the data members are private. However, in some cases
we would like to hide certain functions, may be because they access private data. The access to such
functions should be restricted and therefore we may want to put them in private section.
Only a member function of a class can call a private member function of that class. The private member
function cannot even be called by an object with the help of a dot operator. Let us look at the class definition
below.

class model
{
int x;
void read(void); // private member function
public:
void update(void);
void write(void);
};

We create an object m of class model. Now,

m.read(); // does not work as objects cannot access private members

is not effective. But the function update() can invoke the function read() to modify the value of x.

void model :: update(void)


{
read(); // no object used; simple call
}

Program: find out Prime Number using Class.

#include<iostream>
#include<conio.h>
using namespace std;

class prime
{
int m, n, k;
public:
prime(int p)
{
m=p;
}
void cal()
{
n=1;
{
for(k=2;k<=m/2;k++)
if(m%k==0)
{
n=0;
break;
}
else
{
n=1;
}
}
}
void display()
{
if(n==1)
cout<<"\n"<<m<<" is Prime Number.";
else
cout<<"\n"<<m<<" is Not Prime Number.";
}
};
int main()
{
int m;
cout<<"Enter the Number:";
cin>>m;
prime object(m);
object.cal();
object.display();
getch();
return 0;
}

Output1:

Output2:
Static Member Functions

Just like static member variables, C++ allows us to declare member functions as static. A static member
function has the following characteristics:
 A member function that is declared static can only access other static members (functions or
variables) which have been declared inside the same class.
 We
 We can only use the class name and not any of its objects to invoke a static member function. The
syntax is as follows:

class-name :: function-name;

Program below illustrates the implementation of these characteristics. The usage of static member function
showquantity() is to show the number of objects created till that instant. The static variable quantity
maintains the count of the objects created. To display the code number of each object the function
showvalue() is used.

Program: static member function

#include<iostream>
using namespace std;
class sample
{
int value;
static int quantity; // static member variable
public:
void setvalue(void)
{
value = ++quantity;
}
void showvalue(void)
{
cout << "object number is " << value << "\n";
}
static void showquantity(void) // static member function
{
cout << "count is " << quantity << "\n";
}
};
int sample :: quantity;
int main()
{
sample s1, s2;
s1.setvalue();
s2.setvalue();

sample :: showquantity(); // access static function

sample s3;
s3.setvalue();

sample :: showquantity();

s1.showvalue();
s2.showvalue();
s3.showvalue();

return 0;
}

Output:

count is 2
count is 3
object number is 1
object number is 2
object number is 3

You should note that the following statement

value = ++quantity;

is executed whenever setvalue() function is invoked and the current value of quantity is assigned to value.
Since each object has its own copy of value, the data contained in value represents a unique number of its
object.
We should remember that the following function definition is not valid.

static void showquantity()


{
cout << value; // value is not static
}

5.6 Constructors
We need to understand the need of constructor and destructor. One of the main reasons to use constructor
is to initialize the data members of object during object creation. Program below will help you to understand
in better way:

Program: example 1 of Constructor

#include <iostream>
using namespace std;
class sample
{
int a; //by default private
public:
void set_a(int i)
{
a=i;
}
int print_a() { return a; }
};
int main()
{
sample s; // here object of class sample is created
s.set_a(4); // will explicitly set the value of a as 3
cout<<s.print_a(); // will print the value 3
return 0;
}

Output:

In the above program, we call member function set_a() to initialize the variable a explicitly. It would be
much better, if this kind of initialization happened automatically along with object creation. To understand
this, see the program below:

Program: example 2 of Constructor

#include <iostream>
using namespace std;
class sample
{
int a;
public:
sample() // default constructor

{
a=4;
}
sample(int i) // parameterized constructor
{
a=i;
}
sample(const sample &b) // copy constructor
{
a=b.a;
}
int get_a()
{
return a;
}
};

int main()
{
sample s; // default constructor set value of a as 4
sample t(3); // parameterized constructor set value of a as 3
sample b = t; // will copy the values of t to b
cout<<s.get_a() << endl; // will print the value 4
cout<<t.get_a() << endl; // will print the value 3
cout<<b.get_a() << endl; // will print the value 3
return 0;
}

Output:
4
3
3

In the just above programme, it is clear that we can initialize the data members of object as soon as we
create object of that particular class. Later in this chapter we will learn default constructor, parameterized
constructor, copy constructor in details. So, in a nutshell, we can list out the need of constructor for a class
as below:
 When you want to initialise the data member of the class with some default values.
 When you want to initialise the data members of the class with arguments passed to the constructor.
 When you want to carry out any work like allocating space or other resources when an object is
created.

Now, we can define constructor. Constructor is a special member function of a class that Complier invokes
automatically when object is being created to allow the object to initialize itself.

Characteristics of Constructor:

1. A Constructor has same the name as that of a class.


2. Constructors have no return type at all, not even void and hence can’t return any values.
3. The main function of constructor is to initialize objects and allocate appropriate memory to
objects.
4. Constructors are executed when an object is declared.
5. Constructors must be declared as public.
6. They are invoked directly when an object is created.
7. They can’t be inherited. But a derived class can call the base class constructor.
8. They can have default arguments just like other C++ functions.
9. Constructors can be outside the class definition or inside the class definition.
10. Constructors can’t be virtual.
11. Constructors can’t be friend function.
12. Constructors can’t be used in union.
13. They make implicit call to operator new and operator delete when memory allocation is needed.
14. Initialization of the class objects becomes necessary after declaring the constructor.
Following is the syntax to define the constructor.

class class-name
{
access specifier:
member variables should be same
member functions
public:
class-name () //constructor
{
// code of constructor
}
}

Let us have a look at program below that demonstrates the usage of constructors.

Program: example 3 of Constructor

#include<iostream>
#include<conio.h>
using namespace std;
class A
{
int a,b; // Variable Declaration
public: //Constructor
A()
{
a=5;
b=10;
cout<<"Constructor\n";
}
void Display()
{
cout<<"Values :"<<a<<"\t"<<b;
}
};

int main()
{
A Obj; // Constructor invoked.
Obj.Display();
getch();
return 0;
}

Output:

Constructor
Values: 5 10

Here, the constructor name is same as that of the class name. It has no return type. Constructors can be
defined either outside the class definition or inside the class definition by using the class name and the
scope resolution operator (::).
Program: calculation of Prime Number Using Constructor
#include<iostream>
#include<conio.h>
using namespace std;
class prime
{
int m,n,k;
public:
prime(int p)
{
m=p;
}
void cal()
{
n=1;
{
for(k=2;k<=m/2;k++)
if(m%k==0)
{
n=0;
break;
}
else
{
n=1;
}
}
}
void display()
{
if(n==1)
cout<< "\n\tGiven number is prime Number. ";
else
cout<<"\n\tGiven number is Not prime.";
}
};
int main()
{
int m;
cout<<"\n\tEnter the Number:";
cin>>m;
prime object(m);
object.cal();
object.display();
getch();
}

Output1:

Output2:

Types of Constructors

Constructors are of three types, namely


1. Default constructor
2. Parameterized constructor
3. Copy constructor
1. Default constructor

A default constructor is a constructor that has any one of the following properties:
1. The constructor has no parameters.
2. If the constructor has parameters, then all the parameters have default values.
A default constructor is very significant for initialization of object members. If there is no user defined
constructor in a class (let us say A), the compiler implicitly provides a default parameter less constructor
(let us say A::A() ).
Following example defines a class with two default constructors.

class def_constructor {
public:
def_constructor (); // Default constructor with no arguments
def_constructor (int i = 0); // Default constructor with one default argument
};

Program below illustrates how to define default constructor inside the class.

Program: defining default constructor inside class

#include<iostream>
using namespace std;
class abc
{
public:
abc()
{
cout<<"hello";
}
};
int main()
{
abc a;
return 0;
}

Output:

hello

Program below illustrates how to define default constructor outside the class.
Program: defining default constructor outside class

#include<iostream>
using namespace std;

class Defal
{
public:
int x;
int y;
Defal();
};
Defal::Defal()
{
x=y=0;
}
int main()
{
Defal A;
cout << "Default constructor values of x, y are: "<<
A.x <<" , "<< A.y << "\n";
return 0;
}

Output:

Default constructor values of x, y are: 0,0

2. Parameterized constructor
A constructor which has one or more than one parameters is known as parameterized constructor. With this
Constructor, by passing the appropriate values as argument, we can provide different values to the data
members of different objects.
The following is the syntax for parameterized constructor:

class_name(Argument_List) {
-----
-----
}

Program below demonstrates the usage of parameterized constructors.

Program: example 1 of parameterized constructors

#include<iostream>
using namespace std;
class Cube
{
int side;
public:
Cube(int x)
{
side=x;
}
int get_side()
{
return side;
}
};
int main()
{
Cube c1(10);
Cube c2(20);
Cube c3(30);
cout << c1.get_side() << endl;
cout << c2.get_side() << endl;
cout << c3.get_side() << endl;
}

Output:

10
20
30

Let us look at program below, that is another example of usage of parameterized constructors.

Program: example 2 of parameterized constructors

#include <iostream>
using namespace std;
class code
{
public:
int m;
code(int n); // constructor
};

// Implemention of parameterized constructor


code::code(int n)
{
m = n;
}

int main()
{
code c1(7);
code c2(11);
cout << c1.m << " " << c2.m << "\n";
return 0;
}

Output:

7 11

The compiler will not implicitly define a default constructor if all the constructors that have been defined
are non-default. Therefore, there may not be any default constructor in a class. In the following example a
constructor of type other than default has been defined. So, the compiler does not define a default
constructor and we get an error when we try to create obj2.

class Class1
{
private:
int x;
public:
Class1(int y); // A Constructor
};

Class1 :: Class1(int y)
{
x = y;
}
int main()
{
Class1 obj1(10); // non-default constructor is called
Class1 obj2; // Error: no appropriate default constructor available
return 0;
}

3. Copy Constructor
A copy constructor is a member function which initializes an object using another object of the same class.
Basically, the copy constructor does the following:
 Initialize one object from another of the same type.
 Copy an object to return it from a function.
 Copy an object to pass it as an argument to a function.

The following is the syntax for copy constructor:

class-name (const class-name &obj)


{
// constructor body
}

Figure 5.3: copy constructor

The copy constructor takes a reference to a const parameter. It is const to guarantee that the copy constructor
doesn't change it, and it is a reference because a value parameter would require making a copy, which would
invoke the copy constructor.
C++ calls a copy constructor to make a copy of an object in each of the above cases. If there is no copy
constructor defined for the class, C++ uses the default copy constructor which copies each field, i.e., makes
a shallow copy. For Example,

Figure 5.4: Shallow Copy

Deep copy is possible only with user defined copy constructor. In user-defined copy constructor, we make
sure that pointers (or references) of copied object point to new memory locations.
Figure 5.5: Deep Copy

Let us look at program below to understand copy constructors.

Program: usage of copy constructor


#include<iostream>
using namespace std;
class B
{
private:
int m, n;
public:
B(int m1, int n1)
{
m = m1;
n = n1;
}
// Copy constructor
B(const B &p2)
{
m = p2.m;
n = p2.n;
}
int getm()
{
return m;
}
int getn()
{
return n;
}
};
int main()
{
B p1(5, 10); // Calling Normal constructor
B p2 = p1; // Calling Copy constructor
cout << "p1.m = " << p1.getm() << ", p1.n = " << p1.getn();
cout << "\np2.m = " << p2.getm() << ", p2.n = " << p2.getn();
return 0;
}

Output:

p1.m = 5, p1.n = 10
p2.m = 5, p2.n = 10

Here, p2 is a reference to an object that is being used to initialize another object.

Now question is “When is copy constructor called?”

A Copy Constructor in C++, may be invoked in any of the following situations:

1. When an object of the class is passed an argument to a function.


2. When compiler generates a temporary object.
3. When an object of the class is returned by value.
4. When an object is created on the basis of another object of the same class.

Copy constructor vs Assignment Operator

Copy constructor is called when a new object is created from an existing object, as a copy of the existing
object. Assignment operator is called when an already initialized object is assigned a new value from
another existing object. For Example, which of the following two statements call copy constructor and
which one calls assignment operator?

MyClass t1, t2; //constructor


MyClass t3 = t1; // ----> (1)
t2 = t1; // -----> (2)

In the above example (1) calls copy constrictor and (2) calls assignment operator.

Try to understand following code snippet

class Point
{
public:
...
Point(const Point &p); // copy constructor
...
}
Point::Point(const Point &p)
{
x = p.x;
y = p.y;
}

int main()
{
Point p; // calls default constructor
Point s = p; // calls copy constructor
p = s; // assignment, not copy constructor
return 0;
}

Let us now look at program below that calculates the factorial of a given number using copy constructor.

Program: calculate the factorial of a given number using copy constructor

#include<iostream>
using namespace std;
class factorial
{
int a, j, factj;
public:
factorial(int k) //copy constructor
{
a=k;
factj=1;
}
factorial(const factorial &k)
{
a=k.a;
factj=1;
}
void compute()
{
for(j=1; j<=a; j++)
{
factj=factj*j;
}
}
void show()
{
cout<<"\n Factorial is "<<factj;
}
};
int main()
{
int k;
cout<<"\n Enter the Value : ";
cin>>k;
factorial f(k);
f.compute();
f.show();
factorial g(f); //copy constructor takes an object as an argument.
g.compute();
g.show();
return 0;
}
Output:

Enter the Value : 5

Factorial is 120
Factorial is 120

Now try to understand program in which both the copy constructor and the assignment operator are called
one after another.

Program: calling both copy constructor and assignment operator

#include<iostream>
using namespace std;
class sample
{
public:
sample() {}
sample(const sample &s)
{
cout<<"Copy constructor is called "<<endl;
}
sample operator = (const sample &s)
{
cout<<"Assignment operator is called "<<endl;
}
};
int main()
{
sample s1, s2;
s2 = s1;
sample s3 = s1;
return 0;
}

Output:

Assignment operator is called


Copy constructor is called

Copy constructor is called when a new object is created from an existing object, as a copy of the existing
object. And assignment operator is called when an already initialized object is assigned a new value from
another existing object.

s2 = s1; // calls assignment operator, same as "s2.operator= s1;"


sample s3 = s1; // calls copy constructor, same as "sample s3(s1);"

Constructor Overloading
Having two or more number of constructors in a single class is termed as constructor overloading. All the
constructors have different number of arguments. Depending on the number of arguments, the compiler
executes the appropriate constructor.
The following is the syntax for constructor overloading.

class class-name
{
access specifier:
member variables
member functions
public:
class-name()
{
// code of constructor
}
class-name(variables)
{
// code of constructor
}
};

Program below is an example of constructor overloading.

Program: example 1 of constructor overloading


#include<iostream>
using namespace std;
class A
{
int a,b;
public:
A() //Constructor without Argument
{
a=1;
b=2;
cout<<"\n Constructor without Argument ";
}
A(int x,int y) //Constructor with Argument
{
a=x;
b=y;
cout<<"\n Constructor with Argument ";
}
void Display()
{
cout<<"\nValues :"<<a<<"\t"<<b;
}
};
int main()
{
A Obj(5,10);
A Obj2;// Constructor invoked.
Obj.Display();
Obj2.Display();
return 0;
}

Output:

Constructor with Argument


Constructor without Argument
Values: 5 10
Values: 1 2

In the above program, there are two constructors with different parameters hence overloading the
constructors. Both have the same name as the class name but their parameters are different.

Let us now look at program which is another example of constructor overloading.

Program: example 2 of constructor overloading

#include <iostream>
using namespace std:
class Overclass
{
public:
int x;
int y;
Overclass()
{
x = y = 0;
}
Overclass(int a)
{
x = y = a;
}
Overclass(int a, int b)
{
x = a; y = b;
}
};
int main()
{
Overclass A;
Overclass A1(4);
Overclass A2(8, 12);
cout << "Overclass A's x,y value: " <<
A.x << " , "<< A.y << "\n";
cout << "Overclass A1's x,y value: "<<
A1.x << " ,"<< A1.y << "\n";
cout << "Overclass A2's x,y value: "<<
A2.x << " , "<< A2.y << "\n";
return 0;
}

Output:
Overclass A's x,y value: 0 , 0
Overclass A1's x,y value: 4 ,4
Overclass A2's x,y value: 8 , 12

5.7 Objects as Function Arguments


Objects can also be used as arguments to functions like any other data types. This is usually achieved
through two methods:
 Copy of the object is passed to the function.
 Address of the object is passed to the function.
We call the first method pass-by-value and the second method pass-by-reference. In the first method object
that is used to invoke the function is not affected by any modifications made to the object within the
function. In the second method, the called function directly operates on the actual object which is used in
the call. Therefore, modifications made to the object within the function is reflected on the actual object
also. Programmers prefer pass-by-reference to pass-by-value as in the first case they have to pass the
address only and not the entire object as in the second case.

Program below shows how we can use objects as function arguments. This program finds the duration in
the format of minutes and seconds

Program: objects as function arguments


#include<iostream>
using namespace std;
class duration
{
int minutes;
int seconds;
public:
void getdur(int m, int s)
{
minutes = m;
seconds = s;
}
void putdur(void)
{
cout << minutes << " minutes and ";
cout << seconds << " seconds " << "\n";
}
void total(duration, duration); //declaration with objects as arguments
};
void duration :: total(duration d1, duration d2) // d1,d2 are objects
{
seconds = d1.seconds + d2.seconds;
minutes = seconds/60;
seconds = seconds%60;
minutes = minutes + d1.minutes + d2.minutes;
}
int main()
{
duration D1, D2, D3;
D1.getdur(25,35); // get D1
D2.getdur(30,45); // get D2
D3.total(D1,D2); // D3 = D1 + D2
cout << "D1 = "; D1.putdur(); //display D1
cout << "D2 = "; D2.putdur(); //display D2
cout << "D3 = "; D3.putdur(); //display D3
return 0;
}

Output:

D1 = 25 minutes and 35 seconds


D2 = 30 minutes and 45 seconds
D3 = 56 minutes and 20 seconds

Object D3 calls the member function total() using the objects D1 and D2 as arguments. Therefore total()
is able to access the minutes and seconds variables of D3 directly. However, we use d1.minutes and
d1.seconds to access the members of D1. Similarly we use d2.minutes and d2.seconds to access the
members of D2.
Figure 5.6 illustrates how the members are accessed inside the function total().

minutes 56 d1.minutes 25 d2.minutes 30

seconds 20 d1.seconds 35 d2.seconds 45

(D1 + D2)

D3.total(D1,D2)

Figure 5.6 Accessing members of objects within a called function


We can also pass objects as arguments to non-member functions. But, these functions can be used to access
public member functions only. They cannot be used to access private data members.
A function can receive objects as arguments and also return them. Program below shows how we can create
objects within a function and how they can be returned to another function.

Program: create objects within a function and returning to another function

#include<iostream>
using namespace std;
class complex // a + ib form
{
float a; // this part is real
float b; // this part is imaginary
public:
void get(float real, float imaginary)
{
a = real;
b = imaginary;
}

friend complex total(complex, complex);


void display(complex);
};
complex total(complex x1, complex x2)
{
complex x3; // object x3 is created
x3.a = x1.a + x2.a;
x3.b = x1.b + x2.b;
return(x3); // returns object x3
}
void complex :: display(complex x)
{
cout << x.a << " + i" << x.b << "\n";
}
int main()
{
complex P,Q,R;
P.get(3.1, 5.65);
Q.get(2.75, 1.2);
R = total(P,Q); // R = P + Q
cout << "P = "; P.display(P);
cout << "Q = "; Q.display(Q);
cout << "R = "; R.display(R);
return 0;
}

Output:

P = 3.1 + i5.65
Q = 2.75 + i1.2
R = 5.85 + i6.85

The program adds two complex numbers P and Q to produce a third complex number R and displays all
the three numbers.

5.8 Summary
A class is a method of binding data and its related functions together. If needed, data and its related functions
can be hidden from external usage. A new abstract data type is created when a class is defined. This data
type is used like any other built-in data type. Private members of the class can only be accessed from inside
the class, whereas public members can be accessed from outside the class also. All the variables that are
declared within a class are called its data members, whereas all the functions that are declared within a class
are called its member functions. After declaration of a class, we can construct object (like variables) of the
type by utilizing the name of the class. If a variable is declared as public, it can be accessed directly by an
object. But a variable that is private cannot be accessed directly by an object. A member function can be
defined at two locations, i.e., either inside the definition of the class or outside the definition of the class.
Constructor is a special member function of a class that Complier invokes automatically when object is
being created to allow the object to initialize itself. The three different types of constructors are default
constructor, parameterized constructor and copy constructor. Objects can also be used as arguments to
functions like any other data types. This is usually achieved through two methods. Either the copy of the
object is passed to the function or the address of the object is passed to the function.

5.9 Questions
1. Can we use the same function name for a member function of a class and an outside function in the same
program file? Justify your statement.

2. What do you mean by static data member? Write a simple program to illustrate the usage of static data
members.

3. What is a Constructor. Write down the characteristics of a Constructor.

4. Write a program in C++ to show the usage of default, parameterized and copy constructor.

5. Give an example to show the difference between Copy Constructor and Assignment Constructor.

6. What is static member function? Give an example to show its usage.

7. Member functions can be defined at two locations. Give an illustration of the statement.
8. Write a program to prepare a student record in C++ using classes and object.

9. In C++, objects can be passed as arguments to a function. Write a simple program to show this.

10. What is nesting of member functions. Explain with the help of an example.

5.10 Suggested Readings


1. Object oriented Programming with ANSI and Turbo C++ (Pearson): Ashok N Kamthane
2. Object Oriented Programming with C++, 3/e by E. Balagurusamy, McGraw Hill
3. Lafore, Robert. Object-oriented programming in C++. Pearson Education, 1997.
4. https://www.geeksforgeeks.org/c-classes-and-objects/
5. https://www.studytonight.com/cpp/class-and-objects.php

You might also like