CPP notes
CPP notes
Object
Any entity that has state and behavior is known as an object.
For example: chair, pen, table, keyboard, bike etc.
It can be physical and logical.
Class
Collection of objects is called class. It is a logical entity.
Inheritance
When one object acquires all the properties and behaviours of parent object
i.e. known as inheritance. It provides code reusability.
It is used to achieve runtime polymorphism.
Polymorphism
When one task is performed by different ways i.e. known as polymorphism.
For example: to convince the customer differently, to draw something
e.g. shape or rectangle etc.
Abstraction
Hiding internal details and showing functionality is known as abstraction.
For example: phone call, we don't know the internal processing.
Encapsulation
Binding (or wrapping) code and data together into a single unit is known as
encapsulation.
For example: capsule, it is wrapped with different medicines.
Advantage of OOPs over Procedure-oriented programming language:
1. OOPs makes development and maintenance easier where as in Procedure-oriented
programming language
2. it is not easy to manage if code grows as project size grows.
3. OOPs provide data hiding whereas in Procedure-oriented programming language a
global
data can be accessed from anywhere.C++ Object and Class
4. program is designed using objects and classes in C++.
C++ Object:
In C++, Object is a real world entity, for example, chair, car, pen, mobile,
laptop etc.
Object is an instance of a class. All the members of the class can be accessed
through object.
C++ Class:
In C++, class is a group of similar objects.
It is a template from which objects are created.
It can have fields, methods, constructors etc.
class Student
{
public:
int id; //field or data member
float salary; //field or data member
String name;//field or data member
}
#include <iostream>
using namespace std;
class Student {
public:
int id;//data member (also instance variable)
string name;//data member(also instance variable)
};
int main() {
Student s1; //creating an object of Student Class
s1.id = 3301;
s1.name = "Jaganmohan";
cout<<s1.id<<endl;
cout<<s1.name<<endl;
return 0;
}
Output:
3301
Jaganmohan
#include <iostream>
using namespace std;
class Student {
public:
int id;//data member (also instance variable)
string name;//data member(also instance variable)
void insert(int i, string n)
{
id = i;
name = n;
}
void display()
{
cout<<id<<" "<<name<<endl;
}
};
int main(void) {
Student s1; //creating an object of Student
Student s2; //creating an object of Student
s1.insert(100, "Jagan");
s2.insert(101, "Mohan");
s1.display();
s2.display();
return 0;
}
Output:
100 Jagan
101 Mohan
Another example of C++ class where we are storing and displaying employee
information using method.
#include <iostream>
using namespace std;
class Employee {
public:
int id;//data member (also instance variable)
string name;//data member(also instance variable)
float salary;
void insert(int i, string n, float s)
{
id = i;
name = n;
salary = s;
}
void display()
{
cout<<id<<" "<<name<<" "<<salary<<endl;
}
};
int main(void) {
Employee e1; //creating an object of Employee
Employee e2; //creating an object of Employee
e1.insert(100, "Jagan", 990000);
e2.insert(101, "Mohan", 29000);
e1.display();
e2.display();
return 0;
}
Output:
C++ Constructor
In C++, constructor is a special method which is invoked automatically
at the time of object creation. It is used to initialize the data members of
new object generally. The constructor in C++ has the same name as class or
structure.
#include <iostream>
using namespace std;
class Employee
{
public:
Employee()
{
cout<<"Default Constructor Invoked"<<endl;
}
};
int main(void)
{
Employee e1; //creating an object of Employee
Employee e2;
return 0;
}
Output:
#include <iostream>
using namespace std;
class Employee {
public:
int id;//data member (also instance variable)
string name;//data member(also instance variable)
float salary;
Employee(int i, string n, float s)
{
id = i;
name = n;
salary = s;
}
void display()
{
cout<<id<<" "<<name<<" "<<salary<<endl;
}
};
int main(void) {
Employee e1 =Employee(100, "Jagan", 890000); //creating an object of Employee
Employee e2=Employee(101, "Mohan", 59000);
e1.display();
e2.display();
return 0;
}
Output:
C++ Destructor
A destructor works opposite to constructor;
it destructs the objects of classes.
It can be defined only once in a class. Like constructors,
it is invoked automatically.
Note: C++ destructor cannot have parameters. Moreover, modifiers can't be applied
on destructors.
C++ Constructor and Destructor Example
Example of constructor and destructor in C++ which is called automatically.
#include <iostream>
using namespace std;
class Employee
{
public:
Employee()
{
cout<<"Constructor Invoked"<<endl;
}
~Employee()
{
cout<<"Destructor Invoked"<<endl;
}
};
int main(void)
{
Employee e1; //creating an object of Employee
Employee e2; //creating an object of Employee
return 0;
}
Output:
Constructor Invoked
Constructor Invoked
Destructor Invoked
Destructor Invoked
#include <iostream>
using namespace std;
class Employee {
public:
int id; //data member (also instance variable)
string name; //data member(also instance variable)
float salary;
Employee(int id, string name, float salary)
{
this->id = id;
this->name = name;
this->salary = salary;
}
void display()
{
cout<<id<<" "<<name<<" "<<salary<<endl;
}
};
int main(void) {
Employee e1 =Employee(101, "Jagan", 890000); //creating an object of Employee
Employee e2=Employee(102, "Mohan", 59000); //creating an object of Employee
e1.display();
e2.display();
return 0;
}
Output:
C++ Polymorphism
The term "Polymorphism" is the combination of "poly" + "morphs" which means many
forms.
It is a greek word. In object-oriented programming,
we use 3 main concepts:
Inheritance
Encapsulation
Polymorphism.
3. Overloading is a compile time polymorphism where more than one method is having
the
same name but with the different number of parameters or the type of the
parameters.
3. Overriding is a run time polymorphism where more than one method is having the
same
name, number of parameters and the type of the parameters.
6. It is less flexible as mainly all the things execute at the compile time.
6. It is more flexible as all the things execute at the run time.
#include <iostream>
using namespace std;
class Animal {
public:
void eat(){
cout<<"Eating...";
}
};
class Dog: public Animal
{
public:
void eat()
{ cout<<"Eating bread...";
}
};
int main(void) {
Dog d = Dog();
d.eat();
return 0;
}
Output:
Eating bread...
#include <iostream>
using namespace std;
class Shape { // base class
public:
virtual void draw(){ // virtual function
cout<<"drawing..."<<endl;
}
};
class Rectangle: public Shape // inheriting Shape class.
{
public:
void draw()
{
cout<<"drawing rectangle..."<<endl;
}
};
class Circle: public Shape // inheriting Shape class.
{
public:
void draw()
{
cout<<"drawing circle..."<<endl;
}
};
int main(void) {
Shape *s; // base class pointer.
Shape sh; // base class object.
Rectangle rec;
Circle cir;
s=&sh;
s->draw();
s=&rec;
s->draw();
s=&cir
s->draw();
}
Output:
drawing...
drawing rectangle...
drawing circle...
#include <iostream>
using namespace std;
class Animal { // base class declaration.
public:
string color = "Black";
};
class Dog: public Animal // inheriting Animal class.
{
public:
string color = "Grey";
};
int main(void) {
Animal d= Dog();
cout<<d.color;
}
Output:
Black
C++ Overloading:
C++ Function Overloading:
Function Overloading is defined as the process of having two or more function
with the same name, but different in parameters is known as function overloading in
C++.
In function overloading, the function is redefined by using either
different types of arguments or a different number of arguments.
#include <iostream>
using namespace std;
class Cal {
public:
static int add(int a,int b){
return a + b;
}
static int add(int a, int b, int c)
{
return a + b + c;
}
};
int main(void) {
Cal C; // class object declaration.
cout<<C.add(10, 20)<<endl;
cout<<C.add(12, 20, 23);
return 0;
}
Output:
30
55
#include<iostream>
using namespace std;
int mul(int,int);
float mul(float,int);
int mul(int a,int b)
{
return a*b;
}
float mul(double x, int y)
{
return x*y;
}
int main()
{
int r1 = mul(6,7);
float r2 = mul(0.2,3);
std::cout << "r1 is : " <<r1<< std::endl;
std::cout <<"r2 is : " <<r2<< std::endl;
return 0;
}
Output:
r1 is : 42
r2 is : 0.6
Function Overloading and Ambiguity
When the compiler is unable to decide which function is to be invoked among the
overloaded function, this situation is known as function overloading.
When the compiler shows the ambiguity error, the compiler does not run the program.
Causes of Function Overloading:
Type Conversion.
Function with default arguments.
Function with pass by reference.
C++ Overloading
Type Conversion:
Example.
#include<iostream>
using namespace std;
void fun(int);
void fun(float);
void fun(int i)
{
std::cout << "Value of i is : " <<i<< std::endl;
}
void fun(float j)
{
std::cout << "Value of j is : " <<j<< std::endl;
}
int main()
{
fun(12);
fun(1.2);
return 0;
}
The above example shows an error "call of overloaded 'fun(double)' is ambiguous".
The fun(10) will call the first function. The fun(1.2) calls the second function
according to our prediction. But, this does not refer to any function as in C++,
all the floating point constants are treated as double not as a float.
If we replace float to double, the program works.
Therefore, this is a type conversion from float to double.
#include<iostream>
using namespace std;
void fun(int);
void fun(int,int);
void fun(int i)
{
std::cout << "Value of i is : " <<i<< std::endl;
}
void fun(int a,int b=9)
{
std::cout << "Value of a is : " <<a<< std::endl;
std::cout << "Value of b is : " <<b<< std::endl;
}
int main()
{
fun(12);
return 0;
}
The above example shows an error "call of overloaded 'fun(int)' is ambiguous".
The fun(int a, int b=9) can be called in two ways: first is by calling the function
with one argument, i.e., fun(12) and another way is calling the function with
two arguments, i.e., fun(4,5). The fun(int i) function is invoked with one
argument.
Therefore, the compiler could not be able to select among fun(int i) and
fun(int a,int b=9).
#include <iostream>
using namespace std;
void fun(int);
void fun(int &);
int main()
{
int a=10;
fun(a); // error, which f()?
return 0;
}
void fun(int x)
{
std::cout << "Value of x is : " <<x<< std::endl;
}
void fun(int &b)
{
std::cout << "Value of b is : " <<b<< std::endl;
}
The above example shows an error "call of overloaded 'fun(int&)' is ambiguous".
The first function takes one integer argument and the second function takes a
reference
parameter as an argument.
In this case, the compiler does not know which function
is needed by the user as there is no syntactical difference between the
fun(int) and fun(int &).
For example, C++ provides the ability to add the variables of the user-defined
data type that is applied to the built-in data types.
Where the return type is the type of value returned by the function.
class_name is the name of the class.
operator op is an operator function where op is the operator being overloaded,
and the operator is the keyword.
#include <iostream>
using namespace std;
class Test
{
private:
int num;
public:
Test(): num(8){}
void operator ++() {
num = num+2;
}
void Print() {
cout<<"The Count is: "<<num;
}
};
int main()
{
Test tt;
++tt; // calling of a function "void operator ++()"
tt.Print();
return 0;
}
Output:
#include <iostream>
using namespace std;
class A
{
int x;
public:
A(){}
A(int i)
{
x=i;
}
void operator+(A);
void display();
};
void A :: operator+(A a)
{
int m = x+a.x;
cout<<"The result of the addition of two objects is : "<<m;
}
int main()
{
A a1(5);
A a2(4);
a1+a2;
return 0;
}
Output:
function.
#include <iostream>
using namespace std;
class Animal {
public:
void eat(){
cout<<"Eating...";
}
};
class Dog: public Animal
{
public:
void eat()
{
cout<<"Eating bread...";
}
};
int main(void) {
Dog d = Dog();
d.eat();
return 0;
}
Output:
Eating bread...
There is a necessity to use the single pointer to refer to all the objects of the
different classes. So, we create the pointer to the base class that refers to all
the
derived objects.
But, when base class pointer contains the address of the derived class object,
always executes the base class function.
This issue can only be resolved by using the 'virtual' function.
The prototypes of a virtual function of the base class and all the derived classes
must
be identical. If the two functions with the same name but different prototypes,
C++ will consider them as the overloaded functions.
#include <iostream>
using namespace std;
class A
{
int x=5;
public:
void display()
{
std::cout << "Value of x is : " << x<<std::endl;
}
};
class B: public A
{
int y = 10;
public:
void display()
{
std::cout << "Value of y is : " <<y<< std::endl;
}
};
int main()
{
A *a;
B b;
a = &b;
a->display();
return 0;
}
Output:
Value of x is : 5
In the above example, * a is the base class pointer.
The pointer can only access the base class members but not the members of the
derived
class. Although C++ permits the base pointer to point to any object derived from
the
base class, it cannot directly access the members of the derived class.
Therefore, there is a need for virtual function which allows the base pointer to
access
the members of the derived class.
#include <iostream>
{
public:
virtual void display()
{
cout << "Base class is invoked"<<endl;
}
};
class B:public A
{
public:
void display()
{
cout << "Derived Class is invoked"<<endl;
}
};
int main()
{
A* a; //pointer of base class
B b; //object of derived class
a = &b;
a->display(); //Late Binding occurs
}
Output:
Derived Class is invoked
A class containing the pure virtual function cannot be used to declare the objects
of
its own, such classes are known as abstract base classes.
The main objective of the base class is to provide the traits to the derived
classes and to create the base pointer used for achieving the runtime polymorphism.
Pure virtual function can be defined as:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void show() = 0;
};
class Derived : public Base
{
public:
void show()
{
std::cout << "Derived class is derived from the base class." << std::endl;
}
};
int main()
{
Base *bptr;
//Base b;
Derived d;
bptr = &d;
bptr->show();
return 0;
}
Output:
Abstract class
Interface
Abstract class and interface both can have abstract methods which are necessary for
abstraction.
Example of abstract class in C++ which has one abstract method draw().
Its implementation is provided by derived classes: Rectangle and Circle.
Both classes have different implementation.
#include <iostream>
using namespace std;
class Shape
{
public:
virtual void draw()=0;
};
class Rectangle : Shape
{
public:
void draw()
{
cout < <"drawing rectangle..." < <endl;
}
};
class Circle : Shape
{
public:
void draw()
{
cout <<"drawing circle..." < <endl;
}
};
int main( ) {
Rectangle rec;
Circle cir;
rec.draw();
cir.draw();
return 0;
}
Output:
drawing rectangle...
drawing circle...
Let's take a real life example of AC, which can be turned ON or OFF, change the
temperature, change the mode, and other external components such as fan, swing.
But, we don't know the internal details of the AC, i.e., how it works internally.
Thus, we can say that AC seperates the implementation details from the external
interface.
C++ provides a great level of abstraction. For example, pow() function is used to
calculate the power of a number without knowing the algorithm the function follows.
In C++ program if we implement class with private and public members then it is an
example of data abstraction.
Private specifier:
When the members are declared as private, members can only be accessed only by the
member functions of the class.
#include <iostream>
#include<math.h>
using namespace std;
int main()
{
int n = 4;
int power = 3;
int result = pow(n,power); // pow(n,power) is the power function
std::cout << "Cube of n is : " <<result<< std::endl;
return 0;
}
Output:
Cube of n is : 64
In the above example, pow() function is used to calculate 4 raised to the power 3.
The pow() function is present in the math.h header file in which all the
implementation details of the pow() function is hidden.
Advantages Of Abstraction:
1. Implementation details of the class are protected from the inadvertent user
level errors.
3. Data Abstraction avoids the code duplication, i.e., programmer does not have to
undergo the same tasks every time to perform the similar operation.
4. The main aim of the data abstraction is to reuse the code and the proper
partitioning of the code across the classes.
5. Internal implementation can be changed without affecting the user level code
C++ Encapsulation
Encapsulation
The meaning of Encapsulation, is to make sure that "sensitive" data is hidden
from users.
To achieve this, you must declare class variables/attributes as
private (cannot be accessed from outside the class).
If you want others to read or modify the value of a private member,
you can provide public get and set methods.
Example
#include <iostream>
using namespace std;
class Employee {
private:
// Private attribute
int salary;
public:
// Setter
void setSalary(int s) {
salary = s;
}
// Getter
int getSalary() {
return salary;
}
};
int main() {
Employee myObj;
myObj.setSalary(50000);
cout << myObj.getSalary();
return 0;
}
Example
The salary attribute is private, which have restricted access.
The public setSalary() method takes a parameter (s) and assigns it to the salary
attribute (salary = s).
The public getSalary() method returns the value of the private salary attribute.
Why Encapsulation?
It is considered good practice to declare your class attributes as private
(as often as you can). Encapsulation ensures better control of your data,
because you (or others) can change one part of the code without affecting
other parts
Increased security of data