C++ Presentation 2
C++ Presentation 2
C++ Presentation 2
• Part of the meaning of the word encapsulation is the idea of "surrounding" an entity, not just to keep what's inside
together, but also to protect it.
• In object orientation, encapsulation means more than simply combining attributes and behavior together within a
class; it also means restricting access to the inner workings of that class.
• The key principle here is that an object only reveals what the other application components require to effectively
run the application. All else is kept out of view. This is called data hiding. For example, if we take our
BankAccount class, we do not want some other part of our program to reach in and change the balance of any
object, without going through the deposit() or withdraw() behaviours. We should hide that attribute, control access
to it, so it is accessible only by the object itself. This way, the balance cannot be directly changed from outside of
the object and is accessible only using its methods.
• This is also known as "black boxing", which refers to closing the inner working zones of the object, except of the
pieces that we want to make public.
• This allows us to change attributes and implementation of methods without altering the overall program. For
example, we can come back later and change the data type of the balance attribute.
• Another example is medicine which must be protected from humidity and other contamination which may change
its chemical properties, inoder to do so they are covered in a capsule pill this process is known as encapsulation
i.e the pill has encapsulated the medicine
Encapsulation
Consider a real life example of encapsulation, 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”. In the above example the data of any of the section like sales, finance or accounts is hidden from
any other section.
• Access specifiers are used to set access levels to particular members of the class.
• The three levels of access specifiers are public, protected, and private.
• A public member is accessible from outside the class, and anywhere within the scope of the class object.
• In summary the benefits of encapsulation are:
• A setter is a method which initialises the members of a class while a getter will retrieve what has been initialised.
#include <iostream>
#include <string>
using namespace std;
class myClass {
public:
void setName(string x) {
name = x;
}
string getName() {
return name;
}
private:
string name;
};
int main() {
myClass myObj;
myObj.setName("John");
cout << myObj.getName();
return 0;
}
Encapsulation
//Outputs "John"
We used encapsulation to hide the name attribute from the outside code. Then we provided access to it
using public
methods. Our class data can be read and modified only through those methods. This allows for changes
to the
implementation of the methods and attributes, without affecting the outside code.
returntype getVariableName( ){
return instance_variable;
}
Encapsulation
• Access specifiers are used to set access levels to particular members of the class.
• The three levels of access specifiers are public, protected, and private.
• A public member is accessible from outside the class, and anywhere within the scope of the class
object.
#include <iostream>
#include <string>
using namespace std;
class myClass {
public:
void setName(string x) {
name = x;
}
string getName() {
return name;
}
private:
string name;
};
int main() {
myClass myObj;
myObj.setName("John");
cout << myObj.getName();
Inheritance
• One of the most important concepts in object-oriented programming is that of inheritance
• Inheritance allows us to define a class in terms of another class, which makes it easier to
create and maintain an application. This also provides an opportunity to reuse the code
functionality and fast implementation time.
• -When creating a class, instead of writing completely new data members and member
functions, the programmer can designate that the new class should inherit the members
of an existing class. This existing class is called the base class, and the new class is
referred to as the derived class.
• Base and Derived Classes:
• A class can be derived from more than one class, which means it can inherit data and
functions from multiple base classes. To define a derived class, we use a class derivation
list to specify the base class(es). A class derivation list names one or more base classes
and has the form:
• class derived-class: access-specifier base-class Where access-specifier is one of public,
protected, or private, and base-class is the name of a previously defined class. If the
access-specifier is not used, then it is private by default.
• A derived class inherits all base class methods with the following exceptions:
∙ Constructors, destructors and copy constructors of the base class.
∙ Overloaded operators of the base class.
∙ The friend functions of the base class.
∙ Private members of the existing class
Inheritance
• A derived class can access all the non-private members of its base class. Thus base-class
members that should not be accessible to the member functions of derived classes should
be declared private in the base class.
• We can summarize the different access types according to who can access them in the
following way:
Visibility forms
• When deriving a class from a base class, the base class may be inherited through public,
protected or private inheritance. The type of inheritance is specified by the
access-specifier as explained above.
• We hardly use protected or private inheritance but public inheritance is commonly
used. While using different type of inheritance, following rules are applied:
• Public Inheritance: When deriving a class from a public base class, public members of
the base class become public members of the derived class and protected members of
the base class become protected members of the derived class. A base class's private
members are never accessible directly from a derived class, but can be accessed through
calls to the public and protected members of the base class.
• Protected Inheritance: When deriving from a protected base class, public and
protected members of the base class become protected members of the derived class.
• Private Inheritance: When deriving from a private base class, public and protected
members of the base class become private members of the derived class.
Types of inheritance
Syntax for inheritance
class base_class{
...
};
};
Single inheritance
#include <iostream>
using namespace std;
// Base class
class Shape {
protected:
int width; int height;
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}};
class Rectangle: public Shape{
public:
int getArea() {
return (width * height);
}};
int main(){
Rectangle Rect;
Rect.setWidth(5); Rect.setHeight(7);
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}
Multiple inheritance
#include <iostream>
using namespace std;
// Base class Shape
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width; int height;
};
// Base class PaintCost
class PaintCost {
public:
int getCost(int area) {
return area * 70;
}};
// Derived class
class Rectangle: public Shape, public PaintCost{
public: int getArea() {
return (width * height);
}};
Multiple inheritance
int main(void){
Rectangle Rect;
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl; // Print the total cost of painting
cout << "Total paint cost: $" << Rect.getCost(area) << endl;
return 0;
}
Polymorphism
• The process of representing one Form in multiple forms is known as Polymorphism. Here one form
represent original form or original method always resides in base class and multiple forms
represents overridden method which resides in derived classes.
• Polymorphism is derived from 2 greek words: poly and morphs. The word "poly" means many
and morphs means forms. So polymorphism means many forms.
• C++ polymorphism means that a call to a member function will cause a different function to
be executed depending on the type of object that invokes the function.
• The word polymorphism means having many forms. In simple words, we can define polymorphism
as the ability of a message to be displayed in more than one form.
Real life example of polymorphism, a person at a same time can have different characteristic. Like a
man at a same time is a father, a husband, a employee. So a same person posses have different
behavior in different situations. This is called polymorphism.
• Polymorphism is considered as one of the important features of Object Oriented Programming.
• Example
• Suppose if you are in class room that time you behave like a student, when you are in market at that
time you behave like a customer, when you at your home at that time you behave like a son or
daughter, Here one person have different-different behaviors.
Polymorphism
• In C++ polymorphism is mainly divided into two types:
• Compile time Polymorphism
• Runtime Polymorphism
1. Compile time polymorphism: This type of polymorphism is achieved by function overloading or
operator overloading.
Function Overloading: When there are multiple functions with same name but different
parameters then these functions are said to be overloaded.
Functions can be overloaded by change in number of arguments or/and change in type of
arguments or interchanging the order of arguments.
Compile time Polymorphism Example
#include <iostream>
using namespace std;
class Example{
public:
void func(int x){
cout << "value of x is " << x << endl;
}
void func(double x) {
cout << "value of x is " << x << endl;
}
// function with same name and 2 int parameters
void func(int x, int y) {
cout << "value of x and y is " << x << ", " << y << endl;
}
};
int main() {
Example obj1;
// Which function is called will depend on the parameters passed
// The first 'func' is called
obj1.func(7);
// The second 'func' is called
obj1.func(9.132);
// The third 'func' is called
obj1.func(85,64);
return 0; }
Runtime Polymorphism Example
• This type of polymorphism is achieved by Function Overriding. Function overriding on the
other hand occurs when a derived class has a definition for one of the member functions of
the base class. That base function is said to be overridden.
• Virtual function : While declaring a function as virtual, the keyword virtual must precede the
signature of the function. Every derived class redefines the virtual function for its own need.
• Uses of virtual function enable run time polymorphism. We can use base class pointer to point any
derived class object. When a base class contains a virtual function and base class pointer points to a
derived class object as well as the derived class has a redefinition of base class virtual function, then
the determination of which version of that function will be called is made on run time. Different
versions of the function are executed based on the different type of object that is pointed to.
• While using virtual functions:
– · It should be a member function of a class.
public:
virtual void showInfo() {
cout << "Player class info" << endl;
}
};
class Footballer : public Player {
public :
void showInfo() {
cout << "Footballer class info" << endl;
} };
class Cricketer : public Player {
public :
void showInfo() {
cout << "Cricketer class info" << endl;
} };
Runtime Polymorphism Example
int main() {
Player *pPl,p1;
pPl = &p1;
Footballer f1;
Cricketer c1;
pPl->showInfo();
pPl = &f1;
pPl->showInfo();
pPl = &c1;
pPl->showInfo();
return 0;
}
Runtime Polymorphism Example
In the above example, Player is the base class, Footballer and Cricketer are the derived class from Player. Virtual
function showInfo is defined in Player class. Then it is redefined in Footballer and Cricketer class. Here, pPl is the
Player class pointer, p1, f1 and c1 are Player, Footballer and Cricketer class object.
At first, pPl is assigned the address of p1, which is a base class object. If showInfo is now called using pPl, showInfo
function of base class is executed. Next, pPl points to address derived class (Footballer & Cricketer) . If showInfo is
called now, the redefined showInfo function of Footballer & Cricketer class are executed. The key point is, which
version of the showInfo function will be executed depends on which object is currently pointed by base class pointer.
This decision is taken in run time, so it is an example of a run time polymorphism. This type of runtime polymorphism
using virtual function is achieved by the base class pointer.
Runtime Polymorphism Example
#include <iostream>
#include <string>
#define PI 3.14159
using namespace std;
class Shape //Base class {
public:
Shape() {}
double area_calc() {
return 0;
} };
class Rect : public Shape //"Rect" derives from "Shape" {
public:
double width, height;
Rect(double w = 2, double h = 2) {
width = w; height = h; }
double area_calc() {
return width*height;
} };
Runtime Polymorphism Example
class Circle : public Shape //"Circle" derives from "Shape" {
public:
double radius;
Circle(double r = 2) {
radius = r;
}
double area_calc() {
return PI*radius*radius;
} }; i
nt main() {
Circle circ;
Rect rect;
Shape* ptr = ˆ //ptr -> circ
cout << "circ area: " << ptr->area_calc() << endl;
ptr = ▭ //ptr -> rect
cout << "rect area: " << ptr->area_calc() << endl;
return 0;
}.
Virtual Classes
- An ambiguity can arise when several paths exist to a class from the same base class. This means that
a child class could have duplicate sets of members inherited from a single base class.
- C++ solves this issue by introducing a virtual base class. When a class is made virtual, necessary
care is taken so that the duplication is avoided regardless of the number of paths that exist to the
child class.
- The ambiguity is also referred to as the diamond problem shown below
Virtual Classes: Situation
#include<iostream>
return (a+b+c+d);
}
};
int main(){
ClassD obj;
obj.a = 100; //Statement 1, Error occurs
obj.b = 20;
obj.c = 30;
obj.d = 40;
cout<<obj.sum();
return 0;
}
• In the above example, both ClassB & ClassC inherit ClassA, they both have single copy
of ClassA. However ClassD inherit both ClassB & ClassC, therefore ClassD have two
copies of ClassA, one from ClassB and another from ClassC.
• Statement 1 in above example will generate error, bco'z compiler can't differentiate
between two copies of ClassA in ClassD.
• To remove multiple copies of ClassA from ClassD, we must
inherit ClassA in ClassBand ClassC as virtual class.
Virtual Classes
#include<iostream>
public:
int sum;
int add(){
return (i+j+k);
}
};
int main(){
D ob;
return 0;
}
• According to the above example, ClassD have only one copy of ClassA and statement 4 will overwrite the value of a, given in
statement 3.
Abstract Classes
• Abstract Class is a class which contains at least 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.
• A template is a blueprint or formula for creating a generic class or a function. The library containers like iterators and
algorithms are examples of generic programming and have been developed using template concept.
• Templates are powerful features of C++ which allows you to write generic programs. In simple terms, you can create a
single function or a class to work with different data types using templates.
• Templates are often used in larger codebase for the purpose of code reusability and flexibility of the programs.
• Template is simple and yet very powerful tool in C++. The simple idea is to pass data type as a parameter so that we don’t need to
write same code for different data types. For example a software company may need sort() for different data types. Rather than
writing and maintaining the multiple codes, we can write one sort() and pass data type as a parameter.
• A single function template can work with different data types at once but, a single normal function can only work with one
set of data types.
• Normally, if you need to perform identical operations on two or more types of data, you use function overloading to create
two functions with the required function declaration.
• However, a better approach would be to use function templates because you can perform the same task writing less and
maintainable code.
Generic Programming/Templates
• How to declare a function template?
• A function template starts with the keyword template followed by template parameter/s inside < > which is
followed by function declaration.
• Large() function returns the largest among the two arguments using a simple conditional operation.
• Inside the main() function, variables of three different data types: int, float and char are declared. The variables are
then passed to the Large() function template as normal functions.
• During run-time, when an integer is passed to the template function, compiler knows it has to generate
a Large() function to accept the int arguments and does so.
• Similarly, when floating-point data and char data are passed, it knows the argument data types and generates
the Large() function accordingly.
• This way, using only a single function template replaced three identical normal functions and made your code
maintainable.
Generic Programming- Example 2
#include <iostream>
using namespace std;
int square (int x) {
return x * x;
};
float square (float x) {
return x * x;
};
double square (double x) {
return x * x;
};
int main()
{
int i, ii;
float x, xx;
double y, yy;
i = 2;
x = 2.2;
y = 2.2;
ii = square(i);
cout << i << ": " << ii << endl;
xx = square(x);
cout << x << ": " << xx << endl;
yy = square(y);
cout << y << ": " << yy << endl;
return 0;
}
Generic Programming- Solution using a template function
#include <iostream>
using namespace std;
template <class T>
inline T square(T x){
T result;
result = x * x;
return result;
};
int main()
{
int i, ii;
float x, xx;
double y, yy;
i = 2;
x = 2.2;
y = 2.2;
ii = square<int>(i);
cout << i << ": " << ii << endl;
xx = square<float>(x);
cout << x << ": " << xx << endl;
// Explicit use of template
yy = square<double>(y);
cout << y << ": " << yy << endl;
// Implicit use of template
yy = square(y);
cout << y << ": " << yy << endl;
return 0;
}
Working with multiple data types
Pra
1. Implement a function template to pass an array of different data types and display the elements
Question
1. Implement a function template to pass an array of different data types and display the elements
#include<iostream.h>
template<class T>
void max(T a[],T &m,int n)
{
for(int i=0;i<n;i++)
if(a[i]>m)
m=a[i];
}
int main()
{
int x[5]={10,50,30,40,20};
int m=x[0];
max(x,m,5);
cout<<"\n The maximum value is : "<<m;
return 0;
}
Class Templates
• Class Templates Like function templates, class templates are useful when a class defines something
that is
• Normally, you would need to create a different class for each data type OR create different member
variables and functions within a single class.
• This will unnecessarily bloat your code base and will be hard to maintain, as a change is one
class/function should be performed on all classes/functions.
• However, class templates make it easy to reuse the same code for all data types.
• How to declare a class template?
template <class T>
class className {
... .. ...
public:
T var;
T someOperation(T arg);
... .. ...
};
Class Templates
• In the above declaration, T is the template argument which is a placeholder for the data type used.
• Inside the class body, a member variable var and a member function someOperation() are both of
type T.
T a, b;
public:
mypair (T first, T second) {
a=first; b=second;
}
T getmax (){
T retval;
retval = a>b? a : b;
return retval; }
};
int main () {
}
Class Templates: Example
#include<iostream>
template<class T>
class Sam{
T first, second;
public:
Sam(T a, T b){
first =a;
second= b;
T bigger(){
return (first>second?first:second);
} };
int main(){
cout<<bo.bigger();
return 0;
}
Class Templates:
• In the above program, a class template Calculator is declared.
• The class contains two private members of type T: num1 & num2, and a constructor to initalize the members.
• It also contains public member functions to calculate the addition, subtraction, multiplication and division of the
numbers which return the value of data type defined by the user. Likewise, a function displayResult() to display
the final output to the screen.
• In the main() function, two different Calculator objects intCalc and floatCalc are created for data
types: int and float respectively. The values are initialized using the constructor.
• Notice we use <int> and <float> while creating the objects. These tell the compiler the data type used for the class
creation.
• This creates a class definition each for int and float, which are then used accordingly.
• Then, displayResult() of both objects is called which performs the Calculator operations and displays the output.
#include<iostream>
using namespace std;
template<class T, class U>
class A {
T x;
U y;
public:
A() { cout<<"Constructor Called"<<endl; }
};
int main() {
A<char, char> a;
A<int, double> b;
return 0;
}