Constructors
• Is a special member function that enables an
object to initialize itself when it is created.
•This is known as automatic initialization of
objects.
•It’s special function because its name is same as
the class name.
•It is invoked whenever an object of its
associated class is created.
A constructor is declared and defined as:
#include<iostream>
using namespace std;
class student
{
int rollno;
int marks;
public:
student () //constructor defined
{
rollno=0;
marks=0;
}
};
int main()
{
student s; //object created
}
So, the object “s” is not only declared of type student but also initialize its data
members rollno, marks to zero.
Characteristics of Constructor
• A constructor name must be the same as that
of its class.
• It is declared with no return type (not even
void).
• It is declared in public section of the class.
• It is automatically invoked when an object is
created.
• It can have default arguments.
Characteristics of Constructor
• It cannot be declared const.
• It cannot refer to its own address.
• It may not be static.
• It may not be virtual.
• It can not be inherited.
Types of Constructor
Constructors
Default Parameterized Copy
Default Constructors
• A constructor having no arguments (or
parameters) is called default constructor.
• No object is created without a constructor.
• If the programmer does not provide initial
values, then the job is done by the compiler
which provides a default constructor for
creating the objects with some dummy values.
#include<iostream>
#include<cstring>
using namespace std;
class employee
{
char name[20];
int basic;
int hra;
public:
employee() // default constructor
{
strcpy (name, ”Mr.”);
basic=1000;
hra=0;
}
void showdata();
};
void employee:: showdata()
{
cout<<“Employee Name:”<<name<<endl;
cout<<“Basic pay:”<<basic<<endl;
cout<<“Hra :”<<hra<<endl;
}
int main()
{
employee emp;
emp.showdata();
return 0;
}
Parameterized Constructors
• A constructor with arguments is called
parameterized constructor.
• It is very useful in a situation where the
programmer wants to initialize various data
elements of different objects with different
values when they are created.
#include<iostream>
using namespace std;
class sample
{
int a, b;
public:
sample ( int x, int y) // parameterized constructor
{
a=x;
b=y;
}
};
Two ways of passing initial values as arguments to a constructor:
1. Explicit call to constructor
Syntax:
classname objectname= function_name(arguments);
eg.
sample obj1= sample(2,9);
2. Implicit call to constructor
Syntax:
classname objectname(arguments);
eg.
sample obj1(2,9);
#include<iostream>
class code
{
int a,b;
public:
code(int i, int j); //parameterized constructor
void display();
};
code:: code(int i, int j) //constructor definition
{
a=i;
b=j;
}
void code::display()
{
cout<<“a=“<<a<<“b=“<<b<<“\n”;
}
int main()
{
code c(5,10); //implicit call to constructor
c.display();
code d:: code(3,9); //explicit call to constructor
d.display();
return 0;
}
Copy Constructors
• The initialization of an object when done by
another object is called Copy constructor.
• If we have an object (obj1) and we want to
create a new object (obj2) initialized with the
contents of obj1, then the copy constructor
should be used.
sample obj1;
sample obj2 (obj1);
Copy Constructors
• The copy constructor is define in the class as a parameterized
constructor receiving an object as argument passed-by-
reference as given below:
class sample
{
…….
…….
public:
sample (sample & obj ); //copy constructor
………
};
#include<iostream>
class code
{
int a,b;
public:
code() { a=0; b=0; }
code (code &i); //copy constructor
void display() {cout<<“a=“<<a<<“b=“<<b<<“\n”; }
};
code:: code( code &i) //constructor definition
{
a=i.a;
b=i.b;
}
int main()
{
code c1, c2 (c1);
cout<< “First object\n”;
c1. display();
cout<< “Second object\n”;
c2. display();
cout<< “Third object\n”;
code c3=c2; //another way to call the copy constructor
c3.display();
return 0;
}
Constructors with Default Arguments
• We can define a constructor with default
arguments.
#include<iostream>
using namespace std;
class interest
{
long int principal, rate, year;
float amount;
public:
interest (int p, int t, int r=10); //default argument
void compute();
};
interest:: interest (int p, int t, int r)
{
principal=p; year=t; rate=r;
}
void interest:: compute()
{
cout<<“Principle=\n”<<principle;
cout<<“Rate=\n”<<rate;
cout<<“Year=\n”<<year;
amount=(principle*year*rate)/100;
cout<<“Amount=“<<amount;
}
int main()
{
interest obj1(2500, 2); //use of default argument
interest obj1(2500, 2, 15);
obj1.compute();
obj2.compute();
return 0;
}
Output:
Principle: 2500
Rate=10
Year=2
Amount=500
Principle=2500
Rate=15
Year=2
Amount=750
Multiple Constructors in a class
(Constructor Overloading)
• We can define more than one constructor in a
class.
• Constructors are the functions and name of all
the constructors in a class is same.
• So, when more than one constructor function
is defined in a class, we say that constructor is
overloaded.
#include<iostream>
using namespace std;
class circle
{
int radius, area;
public:
circle() //default constructor
{
radius=0;
}
circle( int r) //parameterized constructor
{
radius=r;
}
circle( circle &c) //copyd constructor
{
radius=c.radius;
}
void cal()
{
area=3.14*radius*radius;
}
void display()
{
cout<<“The radius of circle is\n”<<radius;
cout<<“The area of circle is \n”<<area;
}
};
int main()
{
circle c1(10);
circle c2(c1);
circle c3;
c1.cal();
c2.cal();
c3.cal();
c1.display();
c2.display();
c3.display();
return 0;
}
Output:
The radius of circle is 10
The area of circle is 314
The radius of circle is 10
The area of circle is 314
The radius of circle is 0
The area of circle is 0
Destructor
• It is used to destroy the object that has been
created by the constructor.
• They are the member functions which have the
same name as that of the class with a tilde sign
(~) proceed their name.
Eg:
~ sample() { };
Characteristics of Destructor
• No arguments can be provided to a destructor.
• It has no return type, not even void.
• They can’t be inherited.
• They can’t be overloaded.
• Destructors are invoked automatically when
the object is destroyed.
• If there is no destructor in a class, a default
destructor is generated by the compiler.
#include<iostream>
using namespace std;
class code
{
int a,b;
public:
code(int i, int j); //parameterized constructor
void display();
~ code();
};
code:: code(int i, int j) //constructor definition
{
a=i;
b=j;
}
void code::display()
{
cout<<“a=“<<a<<“b=“<<b<<“\n”;
}
code::~ code()
{
cout<<“Destructor called”;
}
int main()
{
code c(5,10);
c.display();
return 0;
}
Output:
a=5 b=10
Destructor called
Function Overloading
• It is the process of using the same name for
two or more functions.
• In overloading, each redefinition of the
function must use either different types of
parameters or different number of parameters.
• Only through these differences that the
compiler knows which function to call in any
given situation.
#include <iostream>
using namespace std;
int myfunc(int i); // these differ in types of parameters
double myfunc(double i);
int main()
{
cout << myfunc(10) << " "; // calls myfunc(int i)
cout << myfunc(5.4); // calls myfunc(double i)
return 0;
}
double myfunc(double i)
{
return i;
}
int myfunc(int i)
{
return i;
}
#include <iostream>
using namespace std;
int myfunc(int i); // these differ in number of parameters
int myfunc(int i, int j);
int main()
{
cout << myfunc(10) << " "; // calls myfunc(int i)
cout << myfunc(4, 5); // calls myfunc(int i, int j)
return 0;
}
int myfunc(int i)
{
return i;
}
int myfunc(int i, int j)
{
return i*j;
}
Function Overloading
• Two functions differing only in their return
types cannot be overloaded.
int myfunc(int i); // Error: differing return types are
float myfunc(int i); // insufficient when overloading.
Function Overloading
• Sometimes, two function declarations will
appear to differ, but in fact they do not.
void f(int *p);
void f(int p[]); // error, *p is same as p[]
Function Overloading and Ambiguity
• Sometimes a situation arises in which the compiler is unable to
choose between two overloaded functions. This situation is said to
be ambiguous.
• Ambiguous statements are errors and program will not compile.
• One of the main cause for ambiguity is automatic type conversion.
Eg.
int myfunc(double d);
// ...
cout << myfunc('c'); // not an error, conversion applied
It converts character ‘c’ into its double equivalent, but only few such
conversions are allowed. Such conversions are convenient, but they
cause ambiguity.
#include <iostream>
using namespace std;
float myfunc(float i);
double myfunc(double i);
int main()
{
cout << myfunc(10.1) << " "; // unambiguous, calls myfunc(double)
cout << myfunc(10); // ambiguous
return 0;
}
float myfunc(float i)
{
return i;
}
double myfunc(double i)
{
return -i;
}
• The function “myfunc” is overloaded with argument type as
float or double.
• In unambiguous line myfunc(10.1), the float value is
automatically converted to double.
• But when myfunc() is called with integer value 10, it causes
ambiguity as compiler doesn’t know whether the conversion
has to be done in double or float.
• Ambiguity is also caused by the specific invocation not with the
overloading of function.
#include <iostream>
using namespace std;
char myfunc(unsigned char ch);
char myfunc(char ch);
int main()
{
cout << myfunc('c'); // this calls myfunc(char)
cout << myfunc(88) << " "; // ambiguous
return 0;
}
char myfunc(unsigned char ch)
{
return ch-1;
}
char myfunc(char ch)
{
return ch+1;
}
• In C++, the unsigned char and char are not inherently
ambiguous, but when function myfunc() is called with integer
value 88, the compiler doesn’t know which function to call. It
doesn’t know should 88 be converted into unsigned char or
char.
• Another reason for ambiguity is by using default arguments in
overloaded function.
#include <iostream>
using namespace std;
int myfunc(int i);
int myfunc(int i, int j=1);
int main()
{
cout << myfunc(4, 5) << " "; // unambiguous
cout << myfunc(10); // ambiguous
return 0;
}
int myfunc(int i)
{
return i;
}
int myfunc(int i, int j)
{
return i*j;
}
• The first call to function myfunc() is unambiguous, but when
second call to function arises with one argument value, the
compiler get confused that the function with one parameter
has to take the call or the second function which takes two
arguments with second argument as the default argument.
#include <iostream>
using namespace std;
void f(int x);
void f(int &x); // error
int main()
{
int a=10;
f(a); // error, which f()?
return 0;
}
void f(int x)
{
cout << "In f(int)\n";
}
void f(int &x)
{
cout << "In f(int &)\n";
}
• Two functions cannot be overloaded when the only difference
is that one take a referenced parameter and other takes a
normal parameter i.e. call-by-value parameter.
• The compiler has no way of knowing which version of the
function is intended when it is called.
Friend Function
• In OOPs, the data members declared as private in a class are
restricted from access by non-member functions.
• If attempt is made directly to access these members, will result
in compile time errors.
• Other way is to change private data member to public, but it
goes against the concept of data hiding and data encapsulation.
• Another way to access the private data of class by non-
member function is the use of friend function.
Friend Function
• Friend function is although a non-member function but it has full access rights to
private data members of the class.
• We can declare a function to be a friend of a class within the class declaration by
using the keyword “friend”.
class sample
{
……
public:
friend void abc();
…....
};
void abc() //non member function
{
//body of function
}
Characteristics of Friend Function
• They are not in the scope of a class.
• They are not called using object of that class.
• They cannot access member functions directly rather uses the
objects of the class.
• They can be declared as friend in any part(private or public) of
the class.
• They can be invoked like a normal function without the help
of any object.
• They have the object as arguments.
#include <iostream>
using namespace std;
class abc
{
int a,b;
public:
void setv()
{
a=20;
b=45;
}
friend int sum(abc x); //declaration of friend function
};
int sum(abc x) //friend function definition
{
return(x.a+x.b);
}
int main()
{
abc s;
s.setv();
cout<<sum(s); //calling friend function
return 0;
}
The friend function can be defined within the scope of class definition.
#include <iostream>
using namespace std;
class abc
{
int a,b;
public:
void setv()
{
a=20;
b=45;
}
friend int sum(abc x) //friend function definition
{
return(x.a+x.b);
}
};
int main()
{
abc s;
s.setv();
cout<<sum(s); //calling friend function
return 0;
}
Uses of Friend Function
• Friend functions are useful when we are overloading certain
types of operators.
• Friend functions make the creation of some types of I/O
functions easier.
• Friend functions can be desirable in cases when two or more
classes may contain members that are interrelated.
• Member functions of one class can be friend functions of another class.
• So, they are defined using the scope resolution operator as:
class one
{
…..
….
public:
int sum(); //member function of one
…..
};
class two
{
……
…….
public:
{
friend int one::sum(); //function sum() of one
…..
};
So, function sum() is member of class one and friend of class two.
• A non-member function can be friendly with one or more
classes.
• When a function has declared to have friendship with more
than one class, the friend classes should have forward
declaration as it needs to access the private members of both
classes.
#include<iostream>
using namespace std;
class two; //forward declaration
class one
{
int m;
public:
void getdata()
{
cout<<“Enter the value of m:”;
cin>>m;
}
friend int sum (one, two);
}; //end of class one
class two
{
int n;
public:
void getdata()
{
cout<<“Enter the value of n:”;
cin>>n;
}
friend int sum (one, two);
}; //end of class two
int sum(one a, two b) //definition of friend function
{
return ( a.m + b.n );
}
int main()
{
one x;
two y;
x. getdata ();
y. getdata ();
cout<<“Sum is =“<<sum (x,y); // calling friend function
return 0;
}
Output:
Enter the value of m:23
Enter the value of n:46
Sum is = 69
Friend Classes
• It is also possible to declare all the member functions of one
class as the friend functions of another class.
class three
{
…..
….
friend class one; //all function of class one are
//friends of class three
…..
};
#include <iostream>
using namespace std;
class TwoValues {
int a;
int b;
public:
TwoValues(int i, int j) { a = i; b = j; }
friend class Min;
};
class Min {
public:
int min(TwoValues x);
};
int Min::min(TwoValues x)
{
return x.a < x.b ? x.a : x.b;
}
int main()
{
TwoValues ob(10, 20);
Min m;
cout << m.min(ob);
return 0;
}