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

Unit 2 Encapsulation in C

Encapsulation in C++ involves binding together data and the functions that manipulate that data. It wraps related data and functions into a single unit called a class. This binding and wrapping provides data abstraction and information hiding, where the data is hidden from outside access and can only be accessed and manipulated through member functions of the class. Some key advantages of encapsulation include simplicity, clarity, low complexity, and better program understanding.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
81 views

Unit 2 Encapsulation in C

Encapsulation in C++ involves binding together data and the functions that manipulate that data. It wraps related data and functions into a single unit called a class. This binding and wrapping provides data abstraction and information hiding, where the data is hidden from outside access and can only be accessed and manipulated through member functions of the class. Some key advantages of encapsulation include simplicity, clarity, low complexity, and better program understanding.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 48

Encapsulation in C++

In normal terms Encapsulation is defined as wrapping up of data and


information under a single unit. In Object Oriented Programming,
Encapsulation is defined as binding together the data and the functions that
manipulates them.

Encapsulation also lead to data abstraction or hiding. As using encapsulation


also hides the data. In the above example the data of any of the section like
sales, finance or accounts is hidden from any other section.

Real Life Examples of Information Hiding

 in a company there are different sections like the accounts section, finance
section, sales section etc. The finance section handles all the financial
transactions and keep records of all the data related to finance. Similarly the
sales section handles all the sales related activities and keep records of all
the sales. Now there may arise a situation when for some reason an official
from finance section needs all the data about sales in a particular month. In
this case, he is not allowed to directly access the data of sales section. He
will first have to contact some other officer in the sales section and then
request him to give the particular data. This is what encapsulation is. Here
the data of sales section and the employees that can manipulate them are
wrapped under a single name “sales section”.

 Your name and other personal information is stored in


your brain we can’t access this information directly.
For getting this information we need to ask you about it
and it will be up to you how much details you would like to
share with us.
 An email server may have account information of millions
of people but it will share only our account information
with us if we request it to send anyone else accounts
information our request will be refused.
 A phone SIM card may store several phone numbers but
we can’t read the numbers directly from the SIM card
rather phone-set reads this information for us and if the
owner of this phone has not allowed others to see the
numbers saved in this phone we will not be able to see
those phone numbers using phone.

NOTE
“Hiding the object details (state and behavior) from the users”
Information Hiding is achieved in Object Oriented Programming
using the following principles,
· All information related to an object is stored within the object
· It is hidden from the outside world
· It can only be manipulated by the object itself
Role of access specifiers in encapsulation
access specifiers plays an important role in implementing encapsulation in
C++. The process of implementing encapsulation can be sub-divided into
two steps:
1. The data members should be labeled as private using
the private access specifiers
2. The member function which manipulates the data members should be
labeled as public using the public access specifier

What is Information Hiding in OOP?


Encapsulation supports information hiding by making use of the three access
specifiers of a class.

Public: If a class member is public, it can be used anywhere without the access
restrictions.

Private: if a class member is private, it can be used only by the members and
friends of class.
Protected: if a class member is protected, it can be used only by the members and
friends of class and the members and friends of classes derived from class.

In other words:

C++ supports the properties of encapsulation and data hiding through the
creation of user-defined types, called classes. We already have studied
that a class can contain private, protected and public members. By
default, all items defined in a class are private. For example:

class Box {
public:
double getVolume(void) {
return length * breadth * height;
}

private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};

The variables length, breadth, and height are private. This means that they
can be accessed only by other members of the Box class, and not by any
other part of your program. This is one way encapsulation is achieved.

To make parts of a class public (i.e., accessible to other parts of your


program), you must declare them after the public keyword. All variables or
functions defined after the public specifier are accessible by all other
functions in your program.

Making one class a friend of another exposes the implementation details


and reduces encapsulation. The ideal is to keep as many of the details of
each class hidden from all other classes as possible.
In C++ encapsulation can be implemented using Class and access
modifiers. Look at the below program:

#include<iostream>

using namespace std;

 class Encapsulation

    private:

        // data hidden from outside world

        int x;

        public:

        // function to set value of

        // variable x

        void set(int a)

        {

            x =a;

        }

         

        // function to return value of

        // variable x

        int get()

        {

            return x;

        }

};
 

// main function

int main()

    Encapsulation obj;

     

    obj.set(5);

     

    cout<<obj.get();

    return 0;

Run on IDE

output:

In the above program the variable x is made private. This variable can be
accessed and manipulated only using the functions get() and set() which are
present inside the class. Thus we can say that here, the variable x and the
functions get() and set() are binded together which is nothing but
encapsulation.

Advantages of Information Hiding


Following are two major advantages of information hiding. It
simplifies our Object Oriented Model:
As we saw earlier that our object oriented model only had objects
and their interactions hiding implementation details so it makes it
easier for everyone to understand our object oriented model. It is a
barrier against change propagation. As implementation of functions
is limited to our class and we have only given the name of functions
to user along with description of parameters so if we change
implementation of function it doesn’t affect the object oriented
model.
We can achieve information hiding using Encapsulation and
Abstraction, so we see these two concepts in detail now.
Advantages of Encapsulation

The following are the main advantages of Encapsulation,

Simplicity and clarity

As all data and functions are stored in the objects so there is no


data or function around in program that is not part of any object
and is this way it becomes very easy to understand the purpose of
each data member and function in an object.

Low complexity

As data members and functions are hidden in objects and each


object has a specific behavior so there is less complexity in code
there will be no such situations that a functions is using some other
function and that functions is using some other function.

Better understanding

Everyone will be able to understand whole scenario by simple


looking into object diagrams without any issue as each object has
specific role and specific relation with other objects.

Abstract Data Type - What is an Abstract Data Type (ADT)?


An abstraction is a simplified description, or specification, of a system that
focuses on some essential structure or behavior of a real-world or
conceptual object. A good abstraction is one in which information that is
significant to the user is emphasized while details that are immaterial, at
least for the moment, are suppressed. We use the principles of information
hiding to encapsulate these details.

An abstract data type is a programming language facility for organizing


programs into modules using criteria that are based on the data structures
of the program. The specification of the module should provide all
information required for using the type, including the allowable values of the
data and the effects of the operations. However, details about the
implementation, such as data representations and algorithms for
implementing the operations, are hidden within the module. This separation
of specification from implementation is a key idea of abstract data types.
Each module that defines an abstract data type may include both data
declarations and subroutine definitions. The criteria for organizing the
modules emphasize protecting the data structures from arbitrary
manipulation- malicious or accidental-by other parts of the program.
Languages that support abstract data types include scope rules that
guarantee this locality by hiding the names of local data from all parts of the
program outside the module that defines the abstract data type. The
objective of organizing a program using abstract data types is to expedite
program development and to simplify maintenance by imposing a certain
kind of predictable and useful structure on the program.
Like structured programming, the methodology of abstract data types
emphasizes locality of related collections of information. In the case of
abstract data types, attention is focused on data rather than on control, and
the strategy is to form modules consisting of a data structure and its
associated operations. The objective is to treat these modules in the same
way as ordinary types, such as integers and reals, are treated; this requires
support for declarations, infix operators, specification of parameters to
subroutines, etc. The resulting abstract data type effectively extends the set
of types available to a program. It explains the properties of a new group of
variables by specifying the values that one of these variables may have, and
it explains the operations that will be permitted on the variables of the new
type by giving the effects the operations have on the values of the variables.
In designing a data type abstraction, we first specify the functional
properties of a data structure and its operations, and then we implement
them in terms of existing language constructs (and other data types) and
show that the specification is accurate. When we subsequently use the
abstraction, we deal with the new type solely in terms of its specification.
This philosophy has been developed in several programming languages,
including Ada, C++, Concurrent Pascal, Euclid, Gypsy, Mesa, Modula, and
Simula.

C++ Classes and Objects


The main purpose of C++ programming is to add object orientation to the C
programming language and classes are the central feature of C++ that
supports object-oriented programming and are often called user-defined
types.

A class is used to specify the form of an object and it combines data


representation and methods for manipulating that data into one neat
package. The data and functions within a class are called members of the
class.

C++ Class Definitions


When you define a class, you define a blueprint for a data type. This doesn't
actually define any data, but it does define what the class name means,
that is, what an object of the class will consist of and what operations can
be performed on such an object.

A class definition starts with the keyword class followed by the class name;


and the class body, enclosed by a pair of curly braces. A class definition
must be followed either by a semicolon or a list of declarations. For
example, we defined the Box data type using the keyword class as follows:

class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};

The keyword public determines the access attributes of the members of


the class that follow it. A public member can be accessed from outside the
class anywhere within the scope of the class object.

In other words :

A class is defined in C++ using keyword class followed by the name of


class. The body of class is defined inside the curly brackets and terminated
by a semicolon at the end.
Define C++ Objects
A class provides the blueprints for objects, so basically an object is created
from a class. We declare objects of a class with exactly the same sort of
declaration that we declare variables of basic types. Following statements
declare two objects of class Box:

Syntax:
ClassName ObjectName;

Box Box1; // Declare Box1 of type Box


Box Box2; // Declare Box2 of type Box

Both of the objects Box1 and Box2 will have their own copy of data
members.

Accessing data members and member functions : The data members and
member functions of class can be accessed using the dot(‘.’) operator with the object. For
example if the name of object is obj and you want to access the member function with the
name printName() then you will have to write obj.printName() .

The public data members are also accessed in the same way given
however the private data members are not allowed to be accessed directly by the object.
Accessing a data member depends solely on the access control of that data member.
This access control is given by Access modifiers in C++. There are three access
modifiers : public, private and protected.
1. Public mode: If we derive a sub class 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.
2. Protected mode: If we derive a sub class 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.
3. Private mode: If we derive a sub class from 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.
// C++ program to demonstrate accessing of data members

#include <iostream.h>

using namespace std;

class Geeks

    // Access specifier

    public:

    // Data Members

    string geekname;

    // Member Functions()

    void printname()

    {

       cout << "Geekname is: " << geekname;


    }

};

int main() {

    // Declare an object of class geeks

    Geeks obj1;

    // accessing data member

    obj1.geekname = "Abhi";

    // accessing member function

    obj1.printname();

    return 0;

Run on IDE

Output:

Geekname is: Abhi

Member Functions in Classes


There are 2 ways to define a member function:
 Inside class definition
 Outside class definition
To define a member function outside the class definition we have to use the scope
resolution :: operator along with class name and function name.
// C++ program to demonstrate function

// declaration outside class

#include <iostream.h>
using namespace std;

class Geeks

    public:

    string geekname;

    int id;

     

    // printname is not defined inside class defination

    void printname();

     

    // printid is defined inside class defination

    void printid()

    {

        cout << "Geek id is: " << id;

    }

};

// Definition of printname using scope resolution operator ::

void Geeks::printname()

    cout << "Geekname is: " << geekname;

int main() {

     

    Geeks obj1;

    obj1.geekname = "xyz";
    obj1.id=15;

     

    // call printname()

    obj1.printname();

    cout << endl;

     

    // call printid()

    obj1.printid();

    return 0;

Run on IDE

Output:

Geekname is: xyz

Geek id is: 15

Note that all the member functions defined inside the class definition are by default inline,
but you can also make any non-class function inline by using keyword inline with them.
Inline functions are actual functions, which are copied everywhere during compilation, like
pre-processor macro, so the overhead of function calling is reduced.

Example: Object and Class


// Program to illustrate the working of objects and class in C++ Programming
#include <iostream>
using namespace std;

class Test
{
private:
int data1;
float data2;
public:

void insertIntegerData(int d)
{
data1 = d;
cout << "Number: " << data1;
}

float insertFloatData()
{
cout << "\nEnter data: ";
cin >> data2;
return data2;
}
};

int main()
{
Test o1, o2;
float secondDataOfObject2;

o1.insertIntegerData(12);
secondDataOfObject2 = o2.insertFloatData();

cout << "You entered " << secondDataOfObject2;


return 0;
}

Output
Number: 12

Enter data: 23.3

You entered 23.3

In this program, two data members data1 and data2 and two member


functions insertIntegerData() and insertFloatData() are defined under Test class.

Two objects o1 and o2 of the same class are declared.

The insertIntegerData() function is called for the o1 object using:

o1.insertIntegerData(12);

This sets the value of data1 for object o1 to 12.

Then, the insertFloatData() function for object o2 is called and the return value


from the function is stored in variable secondDataOfObject2 using:

secondDataOfObject2 = o2.insertFloatData();

Program to Enter Students Details and Display it


Example:

#include <iostream>

using namespace std;

class stud

{
public:

char name[30],clas[10];

int rol,age;

void enter()

cout<<"Enter Student Name: "; cin>>name;

cout<<"Enter Student Age: "; cin>>age;

cout<<"Enter Student Roll number: "; cin>>rol;

cout<<"Enter Student Class: "; cin>>clas;

void display()

cout<<"\n Age\tName\tR.No.\tClass";

cout<<"\n"<<age<<"\t"<<name<<"\t"<<rol<<"\t"<<clas;

};

int main()

class stud s;

s.enter();
s.display();

cin.get(); //use this to wait for a keypress

C++ methods (function) and


attributes
Functions in C++
Functions are used to provide modularity to a program. Creating an application
using function makes it easier to understand, edit, check errors etc.

Syntax of Function
return-type function-name (parameters)

// function-body

 return-type : suggests what the function will return. It can be int, char,
some pointer or even a class object. There can be functions which does not
return anything, they are mentioned with void.
 Function Name : is the name of the function, using the function name it is
called.
 Parameters : are variables to hold values of arguments passed while
function is called. A function may or may not contain parameter list.
 void sum(int x, int y)

 {

 int z;

 z = x + y;

 cout << z;
 }


 int main()

 {

 int a = 10;

 int b = 20;

 sum (a, b);

 }

Here, a and b are sent as arguments, and x and y are parameters which will


hold values of a and b to perform required operation inside function.

 Function body : is he part where the code statements are written.

Declaring, Defining and Calling Function


Function declaration, is done to tell the compiler about the existence of the
function. Function's return type, its name & parameter list is mentioned.
Function body is written in its definition. Lets understand this with help of an
example.
#include < iostream>

using namespace std;

int sum (int x, int y); //declaring function

int main()

int a = 10;

int b = 20;

int c = sum (a, b); //calling function

cout << c;

int sum (int x, int y) //defining function

return (X + y);

Here, initially the function is declared, without body. Then inside main()
function it is called, as the function returns summation of two values, hence z
is there to store the value of sum. Then, at last, function is defined, where the
body of function is mentioned. We can also, declare & define the function
together, but then it should be done before it is called.

Calling a Function
Functions are called by their names. If the function is without argument, it can
be called directly using its name. But for functions with arguments, we have two
ways to call them,

1. Call by Value
2. Call by Reference

Call by Value
In this calling technique we pass the values of arguments which are stored or
copied into the formal parameters of functions. Hence, the original values are
unchanged only the parameters inside function changes.
void calc(int x);

int main()

int x = 10;

calc(x);

printf("%d", x);

void calc(int x)

x = x + 10 ;

Output : 10

In this case the actual variable x is not changed, because we pass argument by
value, hence a copy of x is passed, which is changed, and that copied value is
destroyed as the function ends(goes out of scope). So the variable x inside
main() still has a value 10.
But we can change this program to modify the original x, by making the
function calc() return a value, and storing that value in x.
int calc(int x);

int main()

{
int x = 10;

x = calc(x);

printf("%d", x);

int calc(int x)

x = x + 10 ;

return x;

Output : 20

Call by Reference
In this we pass the address of the variable as arguments. In this case the
formal parameter can be taken as a reference or a pointer, in both the case
they will change the values of the original variable.
void calc(int *p);

int main()

int x = 10;

calc(&x); // passing address of x as argument

printf("%d", x);

void calc(int *p)

*p = *p + 10;

Output : 20

Constructors
Constructors are special type of member functions that initializes
an object automatically when it is created.
OR
Constructors are special class functions which performs initialization of every
object. The Compiler calls the Constructor whenever an object is created.
Constructors iitialize values to object members after storage is allocated to the
object.
class A

int x;

public:

A(); //Constructor

};

While defining a contructor you must remeber that the name of constructor will
be same as the name of the class, and contructors never have return type.
Constructors can be defined either inside the class definition or outside class
definition using class name and scope resolution :: operator.

Syntax
class class-name {

Access Specifier :
Member - Variables
Member - Functions
public:
class-name() {
// Constructor code
}

//... other Variables & Functions


}

class A

int i;

public:

A(); //Constructor declared


};

A::A() // Constructor definition

i=1;

Following example explains the concept of constructor:

Example Program
/* Example Program For Simple Example Program Of Constructor In C++ */

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

using namespace std;

class Example {
// Variable Declaration
int a, b;
public:

//Constructor

Example() {
// Assign Values In Constructor
a = 10;
b = 20;
cout << "Im Constructor\n";
}

void Display() {
cout << "Values :" << a << "\t" << b;
}
};
int main() {
Example Object;
// Constructor invoked.
Object.Display();

// Wait For Output Screen


getch();
return 0;
}

Types of Constructors
Constructors are of three types :

1. Default Constructor
2. Parametrized Constructor
3. Copy COnstructor

Default Constructor
Default constructor is the constructor which doesn't take any argument. It has
no parameter.
Syntax :
class_name ()

{ Constructor Definition }

Example :
class Cube

int side;

public:

Cube()

side=10;
}

};

int main()

Cube c;

cout << c.side;

Output : 10

In this case, as soon as the object is created the constructor is called which
initializes its data members.
A default constructor is so important for initialization of object members, that
even if we do not define a constructor explicitly, the compiler will provide a
default constructor implicitly.
class Cube

public:

int side;

};

int main()

Cube c;

cout << c.side;

Output : 0

In this case, default constructor provided by the compiler will be called which
will initialize the object data members to default value, that will be 0 in this
case.

Parameterized Constructor
These are the constructors with parameter. Using this Constructor you can
provide different values to data members of different objects, by passing the
appropriate values as argument.
In other words
A default constructor does not have any parameter, but if you need, a
constructor can have parameters. This helps you to assign initial value to an
object at the time of its creation as shown in the following example:

Parameterized Constructor Syntax


class class-name {

Access Specifier :
Member - Variables
Member - Functions
public:
class-name(variables) {
// Constructor code
}

//... other Variables & Functions


}

Parameterized Constructor Example Program


/* Example Program For Simple Example Program Of Parameterized Constructor In C++
#include<iostream>
#include<conio.h>

using namespace std;

class Example {
// Variable Declaration
int a, b;
public:

//Constructor
Example(int x, int y) {
// Assign Values In Constructor
a = x;
b = y;
cout << "Im Constructor\n";
}

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

int main() {
Example Object(10, 20);
// Constructor invoked.
Object.Display();

// Wait For Output Screen


getch();
return 0;
}

Sample Output
Im Constructor
Values :10 20

Example :
class Cube

public:

int side;

Cube(int x)

side=x;
}

};

int main()

Cube c1(10);

Cube c2(20);

Cube c3(30);

cout << c1.side;

cout << c2.side;

cout << c3.side;

OUTPUT : 10 20 30

Copy Constructor
These are special type of Constructors which takes an object as argument, and
is used to copy values of data members of one object into other object.

In other words:

A copy constructor is a constructor of the form classname (classname &). The


compiler will use the copy constructor whenever you initialize an instance using
values of another instance of same type. For example,

Sample S1; //default constructor used


Sample S2 = S1; //copy constructor used

In the above code, for the second statement, the compiler will copy the instance
S1 to S2 member by member. If you have not defined a copy constructor, the
compiler automatically, creates it and it is public.

Syntax
class class-name {

Access Specifier :
Member - Variables
Member - Functions
public:
class-name(variable) {
// Constructor code
}

... other Variables & Functions


}

Syntax : Argument In Main Function


ClassName Object1(value);
ClassName Object2=Object1;

Example Program
/* Example Program For Simple Example Program Of Copy Constructor Overloading In C++
#include<iostream>
#include<conio.h>

using namespace std;

class Example {
// Variable Declaration
int a, b;
public:

//Constructor with Argument

Example(int x, int y) {
// Assign Values In Constructor
a = x;
b = y;
cout << "\nIm Constructor";
}
void Display() {
cout << "\nValues :" << a << "\t" << b;
}
};

int main() {
Example Object(10, 20);

//Copy Constructor
Example Object2 = Object;

// Constructor invoked.

Object.Display();
Object2.Display();

// Wait For Output Screen


getch();
return 0;
}

Sample Output
Im Constructor
Values :10 20
Values :10 20

Constructor Overloading
Just like other member functions, constructors can also be overloaded. Infact
when you have both default and parameterized constructors defined in your
class you are having Overloaded Constructors, one with no parameter and other
with parameter.
You can have any number of Constructors in a class that differ in parameter list.
class Student

int rollno;

string name;

public:

Student(int x)

rollno=x;

name="None";

Student(int x, string str)

rollno=x ;

name=str ;

};

int main()

Student A(10);

Student B(11,"Ram");

In above case we have defined two constructors with different parameters,


hence overloading the constructors.
One more important thing, if you define any constructor explicitly, then the
compiler will not provide default constructor and you will have to define it
yourself.
In the above case if we write Student S; in main(), it will lead to a compile time
error, because we haven't defined default constructor, and compiler will not
provide its default constructor because we have defined other parameterized
constructors.

Simple Example Program Of Constructor Overloading

/* Example Program For Simple Example Program Of Constructor Overloading In C++


little drops @ thiyagaraaj.com
Coded By:THIYAGARAAJ MP */

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

using namespace std;

class Example {
// Variable Declaration
int a, b;
public:

//Constructor wuithout Argument

Example() {
// Assign Values In Constructor
a = 50;
b = 100;
cout << "\nIm Constructor";
}

//Constructor with Argument

Example(int x, int y) {
// Assign Values In Constructor
a = x;
b = y;
cout << "\nIm Constructor";
}

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

int main() {
Example Object(10, 20);
Example Object2;
// Constructor invoked.
Object.Display();
Object2.Display();
// Wait For Output Screen
getch();
return 0;
}

Sample Output

Im Constructor
Im Constructor
Values :10 20
Values :50 100

Use of Constructor in C++


Suppose you are working on 100's of Person objects and the default value of a data
member age is 0. Initialising all objects manually will be a very tedious task.

Instead, you can define a constructor that initialises age to 0. Then, all you have to do is
create a Person object and the constructor will automatically initialise the age.

These situations arise frequently while handling array of objects.

Also, if you want to execute some code immediately after an object is created, you can
place the code inside the body of the constructor.
Special Characteristics of Constructors

The constructor functions have certain special characteristics. These are :

 Constructor functions are invoked automatically when the objects are


created.
 If a class has a constructor, each object of that class will be initialized
before any use is made of the object.
 Constructor functions obeys the usual access rules. That is, private and
protected constructors are available only for member and friend
functions, however, public constructors are available for all the functions.
Only the functions that have access to the constructor of a class, can
create an object of the class.
 No return type (not even void) can be specified for a constructor.
 They cannot be inherited, through a derived class can call the base class
constructor.
 A constructor may not be static.
 Default constructors and copy constructors are generated (by the
compiler) where needed. Generated constructors are public.
 Like other C++ functions, constructors can also have default arguments.
 It is not possible to take the address of a constructor.
 An object of a class with a constructor cannot be a member of a union.
 Member functions may be called from within a constructor.
 A constructor can be used explicitly to create new objects of its class
type, using the syntax.
class-name(expression-list)
For example, Sample obj1 = Sample(13,22.42);

Destructors
Destructor is a special class function which destroys the object as soon as the
scope of object ends. The destructor is called automatically by the compiler
when the object goes out of scope.
A destructor will have exact same name as the class prefixed with a tilde
(~) and it can neither return a value nor can it take any parameters.
Destructor can be very useful for releasing resources before coming out of
the program like closing files, releasing memories etc.

The syntax for destructor is same as that for the constructor, the class name is
used for the name of destructor, with a tilde ~ sign as prefix to it.
class A

public:

~A();

};

Destructors will never have any arguments.

Example

#include<iostream>
using namespace std;

class Marks
{
public:
int maths;
int science;

//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

Need for Destructors

During construction of an object by the constructor, resources may be allocated


for use. For example, a constructor may have opened a file and a memory area
may be allotted to it. Similarly, a constructor may have allocated memory to
some other objects.

These allocated resources must be deallocated before the object is destroyed.


Now whose responsibility is it ? A destructor volunteers here for this task and
performs all clean-up tasks (like closing a file, deallocating and releasing
memory area) automatically. Therefore, a destructor is equally useful as a
constructor is.
Some Characteristics of Destructors

The destructors have some special characteristics associated. These are :

 Destructor functions are invoked automatically when the objects are


destroyed.
 You can have only one destructor for a class. In other words, destructors
can't be overloaded.
 If a class has a destructor, each object of that class will be de-initialized
before the object goes out of scope. (Local objects at the end of the block
defining them and global and static objects at the end of the program.)
 Destructor functions also, obey the usual access rules as other member
functions do.
 No argument can be provided to a destructor, neither does it return any
value.
 They cannot be inherited.
 A destructor may not be static.
 It is not possible to take the address of a destructor.
 Member functions may be called from within a destructor.
 An object of a class with a destructor cannot be a member of a union.

C++: Methods of Object Instantiations with Classes

Fundamentally, there are 2 styles when writing methods of object instantiations with class.
1. The first style assigns a variable with the instantiation of the object itself (as seen in type A).
2. The second, goes for a more versatile approach by using a variable to store the address of the
created object (type B).

type A:

int main(int argc, char * argv[])


{
QApplication app(argc,argv);
QWidget window;
window.show();
return app.exec();
}
type B:
int main (int argc, char * argv[])
{
QApplication app(argc,argv);
QWidget *window;
window = new QWidget;
window->show();
return app.exec();
}

C++ Programming Default Arguments (Parameters)

In C++ programming, you can provide default values for function parameters.

The idea behind default argument is simple. If a function is called by passing


argument/s, those arguments are used by the function.

But if the argument/s are not passed while invoking a function then, the default
values are used.

Default value/s are passed to argument/s in the function prototype.

Working of default arguments

Example: Default Argument


// C++ Program to demonstrate working of default argument

#include <iostream>
using namespace std;
void display(char = '*', int = 1);

int main()
{
cout << "No argument passed:\n";
display();

cout << "\nFirst argument passed:\n";


display('#');

cout << "\nBoth argument passed:\n";


display('$', 5);

return 0;
}

void display(char c, int n)


{
for(int i = 1; i <= n; ++i)
{
cout << c;
}
cout << endl;
}

Output

No argument passed:

*
First argument passed:

Both argument passed:

$$$$$

In the above program, you can see the default value assigned to the
arguments void display(char = '*', int = 1); .

At first, display() function is called without passing any arguments. In this


case, display()function used both default arguments c = * and n = 1.

Then, only the first argument is passed using the function second time. In this case,
function does not use first default value passed. It uses the actual parameter
passed as the first argument c = # and takes default value n = 1 as its second
argument.

When display() is invoked for the third time passing both arguments, default
arguments are not used. So, the value of c = $ and n = 5.

Common mistakes when using Default


argument
1. void add(int a, int b = 3, int c, int d = 4);

The above function will not compile. You cannot miss a default argument in
between two arguments.
In this case, c should also be assigned a default value.
 
2. void add(int a, int b = 3, int c, int d);

The above function will not compile as well. You must provide default values for
each argument after b.
In this case, c and d should also be assigned default values.
If you want a single default argument, make sure the argument is the last one. void
add(int a, int b, int c, int d = 4);
 
3. No matter how you use default arguments, a function should always be written so
that it serves only one purpose.
If your function does more than one thing or the logic seems too complicated, you
can use Function overloading to separate the logic better.

C++Programming/Compiler/Linker/Libraries/
Garbage Collection
Garbage collection is a form of automatic memory management. The garbage collector or collector
attempts to reclaim garbage, or memory used by objects that will never be accessed or mutated
again by the application.
Tracing garbage collectors require some implicit runtime overhead that may be beyond the control of
the programmer, and can sometimes lead to performance problems. For example, commonly used
Stop-The-World garbage collectors, which pause program execution at arbitrary times, may make
garbage collecting languages inappropriate for some embedded systems, high-performance server
software, and applications with real-time needs.
A more fundamental issue is that garbage collectors violate locality of reference, since they
deliberately go out of their way to find bits of memory that haven't been accessed recently. The
performance of modern computer architectures is increasingly tied to caching, which depends on the
assumption of locality of reference for its effectiveness. Some garbage collection methods result in
better locality of reference than others. Generational garbage collection is relatively cache-friendly,
and copying collectors automatically defragment memory helping to keep related data together.
Nonetheless, poorly timed garbage collection cycles could have a severe performance impact on
some computations, and for this reason many runtime systems provide mechanisms that allow the
program to temporarily suspend, delay or activate garbage collection cycles.
Despite these issues, for many practical purposes, allocation/deallocation-intensive algorithms
implemented in modern garbage collected languages can actually be faster than their equivalents
using explicit memory management (at least without heroic optimizations by an expert programmer).
A major reason for this is that the garbage collector allows the runtime system to amortize allocation
and deallocation operations in a potentially advantageous fashion. For example, consider the
following program in C++:

#include <iostream>
class A {
int x;
public:
A() { x = 0; ++x; }
};

int main() {
for (int i = 0; i < 1000000000; ++i) {
A *a = new A();
delete a;
}
std::cout << "DING!" << std::endl;
}

One of more widely used libraries that provides this function is Hans Boehm's conservative GC. As
we have seen earlier C++ also supports a powerful idiom called RAII (resource acquisition is
initialization) that can be used to safely and automatically manage resources including memory.

C++ Dynamic Memory


A good understanding of how dynamic memory really works in C++ is
essential to becoming a good C++ programmer. Memory in your C++
program is divided into two parts −

 The stack − All variables declared inside the function will take up memory from
the stack.
 The heap − This is unused memory of the program and can be used to allocate
the memory dynamically when program runs.

Many times, you are not aware in advance how much memory you will need
to store particular information in a defined variable and the size of required
memory can be determined at run time.

You can allocate memory at run time within the heap for the variable of a
given type using a special operator in C++ which returns the address of the
space allocated. This operator is called new operator.
If you are not in need of dynamically allocated memory anymore, you can
use delete operator, which de-allocates memory that was previously
allocated by new operator.

new and delete Operators


There is following generic syntax to use new operator to allocate memory
dynamically for any data-type.

new data-type;

Here, data-type could be any built-in data type including an array or any


user defined data types include class or structure. Let us start with built-in
data types. For example we can define a pointer to type double and then
request that the memory be allocated at execution time. We can do this
using the new operator with the following statements −

double* pvalue = NULL; // Pointer initialized with null


pvalue = new double; // Request memory for the variable

The memory may not have been allocated successfully, if the free store had
been used up. So it is good practice to check if new operator is returning
NULL pointer and take appropriate action as below −

double* pvalue = NULL;


if( !(pvalue = new double )) {
cout << "Error: out of memory." <<endl;
exit(1);
}

The malloc() function from C, still exists in C++, but it is recommended to


avoid using malloc() function. The main advantage of new over malloc() is
that new doesn't just allocate memory, it constructs objects which is prime
purpose of C++.

At any point, when you feel a variable that has been dynamically allocated
is not anymore required, you can free up the memory that it occupies in the
free store with the ‘delete’ operator as follows −

delete pvalue; // Release memory pointed to by pvalue

Let us put above concepts and form the following example to show how
‘new’ and ‘delete’ work −
#include <iostream>
using namespace std;

int main () {
double* pvalue = NULL; // Pointer initialized with null
pvalue = new double; // Request memory for the variable

*pvalue = 29494.99; // Store value at allocated address


cout << "Value of pvalue : " << *pvalue << endl;

delete pvalue; // free up the memory.

return 0;
}

If we compile and run above code, this would produce the following result −

Value of pvalue : 29495

Dynamic Memory Allocation for Arrays


Consider you want to allocate memory for an array of characters, i.e., string
of 20 characters. Using the same syntax what we have used above we can
allocate memory dynamically as shown below.

char* pvalue = NULL; // Pointer initialized with null


pvalue = new char[20]; // Request memory for the variable

To remove the array that we have just created the statement would look
like this −

delete [] pvalue; // Delete array pointed to by pvalue

Following the similar generic syntax of new operator, you can allocate for a
multi-dimensional array as follows −

double** pvalue = NULL; // Pointer initialized with null


pvalue = new double [3][4]; // Allocate memory for a 3x4 array

However, the syntax to release the memory for multi-dimensional array will
still remain same as above −
delete [] pvalue; // Delete array pointed to by pvalue

Dynamic Memory Allocation for Objects


Objects are no different from simple data types. For example, consider the
following code where we are going to use an array of objects to clarify the
concept −

#include <iostream>
using namespace std;

class Box {
public:
Box() {
cout << "Constructor called!" <<endl;
}
~Box() {
cout << "Destructor called!" <<endl;
}
};
int main() {
Box* myBoxArray = new Box[4];
delete [] myBoxArray; // Delete array

return 0;
}

If you were to allocate an array of four Box objects, the Simple constructor
would be called four times and similarly while deleting these objects,
destructor will also be called same number of times.

If we compile and run above code, this would produce the following result −

Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!

Abstract Class
Abstract Class is a class which contains atleast one Pure Virtual function in it. Abstract
classes are used to provide an Interface for its sub classes. Classes inheriting an Abstract
Class must provide definition to the pure virtual function, otherwise they will also become
abstract class.

Characteristics of Abstract Class

1. Abstract class cannot be instantiated, but pointers and refrences of Abstract class type
can be created.
2. Abstract class can have normal functions and variables along with a pure virtual
function.
3. Abstract classes are mainly used for Upcasting, so that its derived classes can use its
interface.
4. Classes inheriting an Abstract Class must implement all pure virtual functions, or else
they will become Abstract too.

Pure Virtual Functions


Pure virtual Functions are virtual functions with no definition. They start with virtual keyword
and ends with = 0. Here is the syntax for a pure virtual function,
virtual void f() = 0;

Example of Abstract Class


class Base //Abstract base class

public:

virtual void show() = 0; //Pure Virtual Function


};

class Derived:public Base

public:

void show()

{ cout << "Implementation of Virtual Function in Derived class"; }

};

int main()

Base obj; //Compile Time Error

Base *b;

Derived d;

b = &d;

b->show();

Output :
Implementation of Virtual Function in Derived class

In the above example Base class is abstract, with pure virtual show() function, hence we
cannot create object of base class.

Why can't we create Object of Abstract Class ?


When we create a pure virtual function in Abstract class, we reserve a slot for a function in
the VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the
VTABLE will be incomplete.
As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation
of object for such class and will display an errror message whenever you try to do so.

Pure Virtual definitions

 Pure Virtual functions can be given a small definition in the Abstract class, which you
want all the derived classes to have. Still you cannot create object of Abstract class.
 Also, the Pure Virtual function must be defined outside the class definition. If you will
define it inside the class definition, complier will give an error. Inline pure virtual
definition is Illegal.

class Base //Abstract base class

public:

virtual void show() = 0; //Pure Virtual Function

};

void Base :: show() //Pure Virtual definition

cout << "Pure Virtual definition\n";

class Derived:public Base

public:

void show()

{ cout << "Implementation of Virtual Function in Derived class"; }

};

int main()

Base *b;

Derived d;

b = &d;

b->show();

Output :
Pure Virtual definition

Implementation of Virtual Function in Derived class

Metaclass
In object-oriented programming, a metaclass is a class whose instances are classes. Just as an
ordinary class defines the behavior of certain objects, a metaclass defines the behavior of certain
classes and their instances. Not all object-oriented programming languages support metaclasses.
Among those that do, the extent to which metaclasses can override any given aspect of class
behavior varies. Metaclasses can be implemented by having classes be first-class citizen, in which
case a metaclass is simply an object that constructs classes. Each language has its own metaobject
protocol, a set of rules that govern how objects, classes, and metaclasses interact. [1]

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy