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

Constructors Continued : Review

The document discusses various aspects of constructors in C++ including default constructors, constructor initialization lists, constructor overloading, constructors with default arguments, copy constructors, destructors, constant objects, constant member functions, pointers to objects, objects as function arguments, returning objects from functions, and static data members. It provides examples for each concept and the expected output.

Uploaded by

Vijay Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views

Constructors Continued : Review

The document discusses various aspects of constructors in C++ including default constructors, constructor initialization lists, constructor overloading, constructors with default arguments, copy constructors, destructors, constant objects, constant member functions, pointers to objects, objects as function arguments, returning objects from functions, and static data members. It provides examples for each concept and the expected output.

Uploaded by

Vijay Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 40

Constructors continued

Review:
A constructor is a special member function of a class that
is used to initialize the data members of an object of the
class.
It is invoked automatically whenever an object of the
class is defined.
A constructor without any argument is called a default
constructor.
If a default constructor is not defined in a program, the
C++ compiler automatically creates one.

class Counter
// use of default constructor
{ private:
unsigned int count;
public:
Counter()
// default constructor
{count = 0;}
void setcount()
{count++;}
int getcount()
{return count;}
};
int main()
{ Counter c1, c2;
cout << c1 =
cout << \nc2 =
c1.setcount();
c2.setcount();
cout << c1 =
cout << \nc2 =
}

<< c1.getcount();
<< c2.getcount();

<< c1.getcount();
<< c2.getcount();

Output:
c1 = 0
c2 = 0
c1 = 1
c2 = 1

Constructor Initialization list:

Most constructors are used mainly to initialize the objects


member data.
Therefore, C++ provide a special syntax for constructors
that simplifies this code:
Counter(): count(0)
{ }
// empty body
Student(int roll, int score): roll_no(roll),
marks(score)
{ }

The list of initial values (separated by commas) in the


constructor definition is called the initialization list.

Constructor overloading:
A class can have multiple constructors. All the
constructors have the same name as the class, and they
differ only in their signatures.

class Account
// constructor overloading
{ private:
int accno; float balance;
public:
Account()
// constructor 1
{cout << Enter the account no. << endl;
cin >> accno;
cout << Enter balance << endl;
cin >> balance;}
Account(int an): accno(an), balance(0.0)
{ }
Account(int ac, float bal):
accno(ac), balance(bal)
{ }

// constructor 2

// constructor 3

void display()
{cout << Account number is << accno << endl;
cout << Balance is << balance << endl;
}
};

int main()
{Account acc1;
// uses constructor 1
Account acc2(100);
// uses constructor 2
Account acc3(200, 950.0); // uses constructor 3
acc1.display();
acc2.display();
acc3.display();
}

Constructor with default arguments:

Like other functions in C++, constructors can also be


defined with default arguments.
If any arguments are passed during the creation of an
object, the compiler selects the suitable constructor with
default arguments.

class Complex
// default arguments
{ private:
float real, imag;
public:
Complex(): real(0.0), imag(0.0)
// constructor 1
{
}
Complex(float rin, float imin = 0.0): // constructor 2
real(rin), imag(imin)
{
}

void display(char* compnum)


{cout << compnum << real;
if(imag < 0)
cout << -i;
else cout << +i;
cout << fabs(imag) << endl;
}
};
// continued ...

int main()
{ Complex c1;
// uses constructor 1
Complex c2(2.0); // uses constructor 2 with
default value for imag
Complex c3(2.5, 1.2); // uses constructor 2 without
any default values
c1.display(c1 = );
c2.display(c2 = );
c3.display(c3 = );
}
Output:
c1 = 0+i0
c2 = 2+i0
c3 = 2.5+i1.2

The Copy Constructor :

A copy constructor copies the data members from one


object to another object of the same type.
Thus it provides another way of initializing objects of a
class.
The syntax for the copy constructor is:
ClassName(const ClassName & an_object);

The copy constructor takes one argument: the object that


is going to get copied. That object is passed by constant
reference because it should not be changed.

class Distance
// use of copy constructor
{ private:
int feet; float inches;
public:
Distance(int ft, float in): feet(ft), inches(in)
{ }
// constructor
Distance(const Distance & d): feet(d.feet), inches(d.inches)
{ }
// copy constructor
void getdist()
{cout << "Enter feet " ; cin >> feet;
cout << "Enter inches "; cin >> inches; }
void showdist()
{cout << feet <<"\' - " << inches << '\"' << endl;}
};
int main()
{ Distance d1(10, 5.5);
Distance d2(d1);
Distance d3 = d1;
cout << "d1 = " ; d1.showdist();
cout << "d2 = " ; d2.showdist();
cout << "d3 = " ; d3.showdist();
}

Output:
d1 = 10 5.5
d2 = 10 5.5
d3 = 10 5.5

The statement,
Distance d2(d1);

initializes one object with another during definition. The


data members of d1 are copied member by member into
d2. It is the default action performed by the copy
constructor.
The following format also has the same effect.
Distance d3 = d1;

It is treated in the same way by the compiler as the


statement,
Distance d3(d1);

Destructors:

When an object is no longer needed, it can be destroyed.


A destructor is a special member function that
automatically executes when an object is destroyed.
The primary usage of destructors is to deallocate memory
that was allocated for the object by the constructor.
A destructor may be invoked explicitly. The syntax of a
destructor is:
~ClassName()
{
// body of destructor
}

A destructor does not take any arguments. Therefore it


cannot be overloaded, and hence only one destructor can
be declared for a class.

class Test
// use of destructor
{public:
Test()
// default constructor
{cout << The object is created <<endl; }

~Test()
// destructor
{cout << The object is destroyed <<endl; }
int main()
{ {Test x;
cout << Now x is alive << endl;}
{Test y;
cout << Now y is alive << endl;}
}

Output: The object is created


Now x is alive
The object is destroyed
The object is created
Now y is alive
The object is destroyed

Constant Objects:
Like other data types, we can also define constant objects
of a class.
The syntax for defining a constant object is:
const ClassName ObjectName(parameters);
Example:

class Distance
{private: int feet; float inches;
public: ...
// public members of Distance

};
int main()
{ const Distance d1(20, 5.5);
...
}

An object declared const cannot be modified.

Constant Member Functions:


A constant member function guarantees that it will never
modify any of its classs member data.
The syntax for defining a constant member function is:
returnType functionName(arguments) const

Thus a function is made a constant function by placing


the keyword const immediately after the declarator.
Example: class Distance
{private: int feet; float inches;
public: ...
void showdist() const
{cout << feet <<"\' - " << inches << '\"' << endl;}
};

Pointers to Objects:
Like other data types, we can define pointers to objects of
a class.
The syntax for defining a pointer to an object is:
ClassName *objectName;
Example: class Distance
{private: int feet; float inches;
public: ...
};
int main()
{Distance *dptr;
dptr = new Distance;
(*dptr).feet = 5; (*dptr).inches = 4.5;
//equivalent to dptr->feet = 5 and dptr->inches = 4.5;
}

Other operations with pointers to objects are similar to as


with pointers to other data types.

Objects as Function Arguments:


Objects can be passed as arguments to a function.
Like any other data type, an object can be passed as an
argument to a function by the following ways:
1. Pass-by-value: a copy of the entire object is passed to the
function.
2. Pass-by-reference by reference parameters: the address of the
object, passed as reference parameter, is passed to the
function.
3. Pass-by-reference by pointers: the address of the object is
passed to the function through a pointer.

The effects of passing objects as arguments by value or


by reference are similar as in the case of ordinary
variables.

class Distance
// objects as function arguments
{ private:
int feet; float inches;
public:
Distance(): feet(0), inches(0.0)
{ }
Distance(int ft, float in): feet(ft), inches(in)
{ }
void getdist()
{cout << "Enter feet " ; cin >> feet;
cout << "Enter inches "; cin >> inches; }
void showdist()
{cout << feet <<"\' - " << inches << '\"' << endl;}
void add_dist(Distance, Distance);
};
void Distance::add_dist(Distance dist1, Distance dist2)
{inches = dist1.inches + dist2.inches;
feet = 0;
if(inches >= 12.0) {inches -= 12.0; feet++; }
feet += dist1.feet + dist2.feet;
}

int main()
{ Distance d1(10, 5.5);
Distance d2(8, 9.7);
Distance d3;
d3.add_dist(d1, d2);
cout << "d1 = " ; d1.showdist();
cout << "d2 = " ; d2.showdist();
cout << "d3 = " ; d3.showdist();
}

Output:
d1 = 10' - 5.5"
d2 = 8' - 9.7"
d3 = 19' - 3.2

Passing objects by reference:


void Distance::add_dist(Distance & dist1, Distance &
dist2)

Passing objects by pointers:


void Distance::add_dist(Distance * distp1, Distance *
distp2)

Function call in this case looks like


d3.add_dist(& d1, & d2);

Returning Objects from Functions:


The return type of a function can be an object. It is similar
to the case of returning an ordinary data type.
The syntax for returning an object from a function is
similar to that of returning values from functions.

class Distance
// function returning objects
{ private:
int feet; float inches;
public:
Distance(): feet(0), inches(0.0)
{ }
Distance(int ft, float in): feet(ft), inches(in)
{ }
void getdist()
{cout << "Enter feet " ; cin >> feet;
cout << "Enter inches "; cin >> inches; }
void showdist()
{cout << feet <<"\' - " << inches << '\"' << endl;}
Distance add_dist(Distance);
};
Distance Distance::add_dist(Distance dist2)
{ Distance x;
x.inches = inches + dist2.inches;
if(x.inches >= 12.0) {x.inches -= 12.0; x.feet = 1; }
x.feet += feet + dist2.feet;
return x;
}

int main()
{ Distance d1(10, 5.5);
Distance d2(8, 9.7);
Distance d3;
d3 = d1.add_dist(d2);
cout << "d1 = " ; d1.showdist();
cout << "d2 = " ; d2.showdist();
cout << "d3 = " ; d3.showdist();
}

Output:
d1 = 10' - 5.5"
d2 = 8' - 9.7"
d3 = 19' - 3.2

Static Data Members:


In some situations it is desirable to have a common data
member.
In such a situation, it would be inefficient to store the
same value in every object of the class.
This can be avoided by using the data member to be
static.
The syntax for defining a static data member of a class is:
class ClassName
{...
static dataType dataMember;
...
};
dataType ClassName::dataMember = initialValue;

A static data member is like a global variable: only one


copy of the variable exists. However, a static data member
may be private.

class Student
// use of public static data member
{public:
static int count; // public static data member
Student() {++count;}
~Student(){--count;}
};
int Student::count = 0;
int main()
{ Student x, y;
cout << Now there are << x.count
{Student x, y, z;
cout << Now there are << x.count
cout << Now there are << x.count
Student z;
cout << Now there are << x.count
}
// Output: 2, 5, 2, 3 students

<< students.\n;
<< students.\n;}
<< students.\n;
<< students.\n;

class Student
// use of private static data member
{private:
static int count; // private static data member
public:
Student() {++count;}
~Student(){--count;}
int numSt() {return count;}
};
//Since count is private, we
int Student::count = 0;

//need the member function


//numst() to read count in main()

int main()
{ Student x, y;
cout << Now there are << x.numSt()
{Student x, y, z;
cout << Now there are << x.numSt()
cout << Now there are << x.numSt()
Student z;
cout << Now there are << x.numSt()
}
// Output: 2, 5, 2, 3 students

<< students.\n;
<< students.\n;}
<< students.\n;
<< students.\n;

Static Member Functions:


C++ also allows defining static member functions.
These static functions can access only the static members
(data or functions) declared in the same class.
Static member functions declared in the public part of a
class can be accessed without specifying an object of that
class.

class Student
// use of static member function
{private:
static int count;
public:
Student() {++count;}
~Student(){--count;}
static int num() {return count;}
};
int Student::count = 0;
int main()
{ Student x, y;
cout << Now there are << Student::num()
{Student x, y, z;
cout << Now there are << Student::num()
cout << Now there are << Student::num()
Student z;
cout << Now there are << Student::num()
}
// Output: 2, 5, 2, 3 students

<< students.\n;
<< students.\n;}
<< students.\n;
<< students.\n;

Friend Functions and Friend Classes:


The concept of data encapsulation and data hiding dictate
that non-member functions should not be allowed to
access the private or protected data members of a class.
However, sometimes we require a function to work on
objects of two different classes.
For this, it is required to allow a non-member function to
access and manipulate the private members of a class.
In C++, this is achieved by using friend functions.
The use of friend functions permits a function or all the
functions of another class to access a different classs
private members.

Standalone functions, entire classes or member functions


of other classes may be declared to be friends of another
class.
To declare a function as a friend of a class, the function
prototype is preceded by keyword friend in the class
definition:
friend return_type function_name (parameters);

The C++ compiler permits the declaration of a friend


function either in a public or a private section, which does
not affect its access right.

class Count
// friend function
{private:
int x;
friend void set_x(Count &, int);
public:
Count(): x(0)
{
}
//constructor
void print() const
{ cout << x << endl;}
};
void set_x(Count &c, int val)
{c.x = val;}
int main()
{ Count counter;
cout << counter.x after instantiation: ;
counter.print();
set_x(counter, 8);
cout << counter.x after call to set_x : ;
counter.print();
}
Output: counter.x after instantiation: 0
counter.x after call to set_x: 8

class Distance
// friend function
{private:
int feet; float inches;
friend void set_dist(Distance &, int, float);
public:
Distance(): feet(0), inches(0.0)
{
}
//constructor
void showdist()
{cout << feet <<"\' - " << inches << '\"' << endl;}
};
void set_dist(Distance & d, int ft, float in)
{d.feet = ft; d.inches = in;}
int main()
{Distance d1;
cout << Distance d1 initially is ;
d1.showdist();
set_dist(d1, 10, 5.5);
cout << Distance d1 after calling set_dist is ;
d1.showdist();
}
Output: Distance d1 initially is 00
Distance d1 after calling set_dist is 10-5.5

Friend Class:
An entire class can be made a friend of another class.
In this case, if Class2 is a friend of Class1, then all the
member functions of Class2 are friends of Class1.
The syntax of declaring a friend class is:
class Class1
{...
friend class Class2;
...
};

The statement
friend class Class2;

declares that all the members of Class2 are friends of


Class1 but not the other way.

class Class1
{friend class Class2;

// friend class

private : int x;
public :
void getdata()

{cout<<Enter a number << endl;


cin>>x;}
};
class Class2

{public :

void disp(class Class1 temp)

{cout<<Entered number is << temp.x << endl;}


};
int main()

{ Class1 obj1;
Class2 obj2;
obj1.getdata();
obj2.disp(obj1);}

Class Friend to a Specified Member Function:


When only specific member function of one class should
be a friend of another class, it must be specified explicitly
using scope resolution operator.
class Class1
{...
friend returnType Class2::class2func(Class1);
...
};

class Class1;

// a member function as friend

class Class2
{public:

void disp(Class1& temp);

};
class Class1
{private : int x;
public :
void getdata()
{cout<<"Enter a number " << endl;

cin >> x;}

friend void Class2::disp(Class1&);


};
void Class2::disp(Class1& temp)
{cout<<"Entered number is
int main()
{Class1 obj1; Class2 obj2;
obj1.getdata();
obj2.disp(obj1);
}

" << temp.x << endl;}

The this Pointer:


Every object has access to its own address through a
pointer called this.
The this pointer is not part of the object itself, rather it
is passed by the compiler as an implicit argument to each
of the objects non-static member functions.
A static member function does not have a this pointer,
because static member functions of a class exist
independently of any objects of a class.
Objects use the this pointer implicitly or explicitly to
reference their data members and member functions.
The type of the this pointer depends on the type of the
object.
Using a this pointer, any member function can find the
address of its object.

class Myclass

// use of this pointer

{private:
char chararray[20];
public:

void show_addr()
{cout<<My objects address is << this << endl;}
};
int main()
{ Myclass c1, c2, c3;
c1.show_addr();

c2.show_addr();
c3.show_addr();
}

Output:
My object's address is 0x22ff20
My object's address is 0x22ff00
My object's address is 0x22fee0

class Myclass

//accessing member data with this

{private:
int x;
public:

void test()
{this->x = 11;
cout << this->x;}
};
int main()
{ Myclass c;

cout << The value of x is ;


c.test();
cout << endl;
}

Output:
The value of x is 11

You might also like