3CS4 OOPS Unit 2
3CS4 OOPS Unit 2
SN CONTENTS Hours
1 Introduction to different programming paradigm, characteristics of OOP, 8
Class, Object, data member, member function, structures in C++,
different access specifiers, defining member function inside and outside
class, array of objects.
2 Concept of reference, dynamic memory allocation using new and delete 8
operators, inline functions, function overloading, function with default
arguments, constructors and destructors, friend function and classes,
using this pointer.
3 Inheritance, types of inheritance, multiple inheritance, virtual base class, 9
function overriding, abstract class and pure virtual function
4 Constant data member and member function, static data member and 9
member function, polymorphism, operator overloading, dynamic binding
and virtual function
5 Exception handling, Template, Stream class, File handling. 6
Total 40
References in C++
A reference variable is an alias, that is, another name for an already existing variable.
Once a reference is initialized with a variable, either the variable name or the reference
name may be used to refer to the variable.
References Pointers
1|P ag e
References are like constant pointers that are automatically dereferences. It is a new
name given to an existing storage. So when you are accessing the reference, you are
actually accessing that storage.
#include<iostream>
using namespace std;
int main () {
// declare simple variables
int i;
double d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}
When the above code is compiled together and executed, it produces the following
result −
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7
2|P ag e
References in Functions
References are generally used for function argument lists and function return values, just
like pointers.
1. When we use reference in argument list, we must keep in mind that any change to the
reference inside the function will cause change to the original argument outside th
function.
2. When we return a reference from a function, you should see that whatever the reference
(*x++);
x++;
int& third ()
int q;
3|P ag e
int& fourth ()
static int x;
int main()
int a=0;
first() takes a pointer as argument and returns a pointer, it will work fine. The returning
pointer points to variable declared outside first(), hence it will be valid even after the first()
ends.
Similarly, second() will also work fine. The returning reference is connected to valid
But in case of third(), we declare a variable q inside the function and try to return a
reference connected to it. But as soon as function third() ends, the local variable q is
x++;
} // ERROR
int main()
4|P ag e
int i=10;
g(i);
We cannot change the argument in the function because it is passed as const reference.
Code Segment: Compiled program with executive instructions are kept in code segment.
It is read only. In order to avoid over writing of stack and heap, code segment is kept
Data Segment: Global variables and static variables are kept in data segment. It is not
read only.
Stack: A stack is usually pre-allocated memory. The stack is a LIFO data structure. Each
new variable is pushed onto the stack. Once variable goes out of scope, memory is freed.
Once a stack variable is freed, that region of memory becomes available for other
5|P ag e
variables. The stack grows and shrinks as functions push and pop local variables. It
stores local data, return addresses, arguments passed to functions and current status of
memory.
Heap: Memory is allocated during program execution. Memory is allocated using new
For example:
int *new_op = new int;
For example:
delete new_op;
The object's extent or the object's lifetime is the time for which the object remains in the
memory during the program execution. Heap Memory allocation is slower than a stack.
In heap there is no particular order in which you can allocate memory as in stack.
delete ex;
But in the above example dangling pointer issue can happen. Wait! what is a dangling
pointer?
In the first figure pointer points to a memory location 1100 which contains a value
25.
In the second figure pointer points to a memory location where object is deleted.
Dangling pointers arise due to object destruction, when an object reference is deleted or
deallocated, without modifying the value of the pointer, so the pointer will keep on
pointing to the same memory location. This problem can be avoided by initializing the
pointer to NULL.
For example:
*ex = new Example();
Delete ex;
ex = NULL;
7|P ag e
What is a Smart Pointer?
Smart Pointer is used to manage the lifetimes of dynamically allocated objects. They
ensure proper destruction of dynamically allocated objects. Smart pointers are defined in
the memory header file.
Smart pointers are built-in pointers, we don't have to worry about deleting them, they are
automatically deleted.
Here is an example of a smart pointer:
S_ptr *ptr = new S_ptr();
ptr->action();
delete ptr;
public:
int x;
// constructor
A()
// object initialization
};
While defining a contructor you must remeber that the name of constructor will be
same as the name of the class, and contructors will never have a return type.
Constructors can be defined either inside the class definition or outside class definition
using class name and scope resolution :: operator.
class A
public:
8|P ag e
int i;
};
// constructor definition
A::A()
i = 1;
1. Default Constructor
2. Parametrized Constructor
3. Copy COnstructor
Default Constructors
Default constructor is the constructor which doesn't take any argument. It has no
parameter.
Syntax:
class_name(parameter1, parameter2, ...)
// constructor Definition
For example:
class Cube
public:
int side;
Cube()
{
9|P ag e
side = 10;
};
int main()
Cube c;
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;
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 or any random integer value in
this case.
10 | P a g e
Parameterized Constructors
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.
For example:
class Cube
public:
int side;
Cube(int x)
side=x;
};
int main()
Cube c1(10);
Cube c2(20);
Cube c3(30);
10
20
30
By using parameterized construcor in above case, we have initialized 3 objects with user
defined values. We can have any number of parameters in a constructor.
11 | P a g e
Copy Constructors
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. We will study copy
constructors in detail later.
public:
int rollno;
string name;
// first constructor
Student(int x)
rollno = x;
name = "None";
// second constructor
rollno = x;
name = str;
};
int main()
Student A(10);
12 | P a g e
// student B initialized with roll no 11 and name John
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.
Destructors in C++
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.
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()
// statement
};
13 | P a g e
// constructor
A()
// destructor
~A()
};
int main()
int x = 1
if(x)
Constructor called
Constructor called
Destructor called
Destructor called
When an object is created the constructor of that class is called. The object reference is
destroyed when its scope ends, which is generally after the closing curly bracket } for the
code block in which it is created.
The object obj2 is destroyed when the if block ends because it was created inside
the if block. And the object obj1 is destroyed when the main() function ends.
14 | P a g e
Single Definition for both Default and Parameterized
Constructor
In this example we will use default argument to have a single definition for both defualt
and parameterized constructor.
class Dual
public:
int a;
Dual(int x=0)
a = x;
};
int main()
Dual obj1;
Dual obj2(10);
Here, in this program, a single Constructor definition will take care for both these object
initializations. We don't need separate default and parameterized constructors.
15 | P a g e
1) Problem with spacing
Let us try to understand this problem using an example,
#define G (y) (y+1)
Here we have defined a Macro with name G(y), which is to be replaced by its value, that
is (y+1) during compilation. But, what actually happens when we call G(y),
G(1) // Macro will replace it
You must be thinking why this happened, this happened because of the spacing in Macro
definition. Hence big functions with several expressions can never be used with macro,
so Inline functions were introduced in C++.
Here precedence of operators will lead to problem, because precedence of & is lower
than that of >, so the macro evaluation will surprise you. This problem can be solved
though using parenthesis, but still for bigger expressions problems will arise.
int x;
public :
16 | P a g e
Inline Functions in C++
Inline functions are actual functions, which are copied everywhere during compilation,
like preprocessor macro, so the overhead of function calling is reduced. All the functions
defined inside class definition are by default inline, but you can also make any non-class
function inline by using keyword inline with them.
For an inline function, declaration and definition must be done together. For example,
inline void fun(int a)
return a++;
1. We must keep inline functions small, small inline functions have better efficiency.
2. Inline functions do increase efficiency, but we should not make all the functions inline.
Because if we make large functions inline, it may lead to code bloat, and might affect the
speed too.
3. Hence, it is adviced to define large functions outside the class definition using scope
resolution :: operator, because if we define such functions inside class definition, then
4. Inline functions are kept in the Symbol Table by the compiler, and all the call for such
// by default private
int price;
public:
17 | P a g e
// getter function for variable price
int getPrice()
return price;
void setPrice(int x)
i=x;
};
Here getPrice() and setPrice() are inline functions, and are made to access the
private data members of the class Auto. The function getPrice(), in this case is
called Getter or Accessor function and the function setPrice() is a Setter or
Mutator function.
There can be overlaoded Accessor and Mutator functions too. We will study overloading
functions in next topic.
compilation, which is negligible for small programs, but it makes a difference in large code
bases.
3. Also, if we require address of the function in program, compiler cannot perform inlining on
such functions. Because for providing address to a function, compiler will have to allocate
storage to it. But inline functions doesn't get storage, they are kept in Symbol table.
int i;
18 | P a g e
public:
int f()
return g()+10;
int g()
return i;
};
int main()
ForwardReference fr;
fr.f();
You must be thinking that this will lead to compile time error, but in this case it will work,
because no inline function in a class is evaluated until the closing braces of class
declaration.
In C++, two functions can have the same name if the number and/or type of
arguments passed is different.
These functions having the same name but different arguments are known as
overloaded functions. For example:
19 | P a g e
Notice that the return types of all these 4 functions are not the same.
Overloaded functions may or may not have different return types but they must
have different arguments. For example,
// Error code
int test(int a) { }
double test(int b){ }
Here, both functions have the same name, the same type, and the same
number of arguments. Hence, the compiler will throw an error.
#include <iostream>
using namespace std;
int main() {
20 | P a g e
}
Output
Absolute value of -5 = 5
Absolute value of 5.5 = 5.5
#include <iostream>
using namespace std;
int main() {
int a = 5;
double b = 5.5;
return 0;
}
Output
21 | P a g e
Integer number: 5
Float number: 5.5
Integer number: 5 and double number: 5.5
Here, the display() function is called three times with different arguments.
Depending on the number and type of arguments passed, the
corresponding display() function is called.
Working of overloading
22 | P a g e
C++ friend Function and friend Classes
Friend Function
1. Friend function not a member function of any class, bcz it is friend of that class.
2. Due to not a member function of any class so it not defines inside the scope of that
class.
3. There is no need to call friend function with the object of any class.
4. Friend function can access private member outside of class .
class Demo
{
private:
int i;
public:
int a,b;
void sum();
}
void main()
{
Demo d1,d2,d3,d4;
d1.sum();
display();
}
23 | P a g e
class MyClass
{
private:
int member1;
};
int main() {
MyClass obj;
However, there is a feature in C++ called friend functions that break this rule
and allow us to access member functions from outside the class.
Similarly, there is a friend class as well, which we will learn later in this
tutorial.
A friend function can access the private and protected data of a class. We
declare a friend function using the friend keyword inside the body of the class.
class className {
... .. ...
friend returnType functionName(arguments);
... .. ...
}
24 | P a g e
Example 1: Working of friend Function
// C++ program to demonstrate the working of friend function
#include <iostream>
using namespace std;
class Distance {
private:
int meter;
// friend function
friend int addFive(Distance);
public:
Distance()
{
Meter=0;
}
};
int main() {
Distance D;
cout << "Distance: " << addFive(D);
return 0;
}
Output
Distance: 5
25 | P a g e
Here, addFive() is a friend function that can access
both private and public data members.
Though this example gives us an idea about the concept of a friend function, it
doesn't show any meaningful use.
#include <iostream>
using namespace std;
// forward declaration
class ClassB;
class ClassA {
public:
// constructor to initialize numA to 12
ClassA() : numA(12) {}
private:
int numA;
};
class ClassB {
public:
// constructor to initialize numB to 1
ClassB() : numB(1) {}
private:
int numB;
26 | P a g e
// friend function declaration
friend int add(ClassA, ClassB);
};
int main() {
ClassA objectA;
ClassB objectB;
cout << "Sum: " << add(objectA, objectB);
return 0;
}
Output
Sum: 13
In this program, ClassA and ClassB have declared add() as a friend function.
Thus, this function can access private data of both classes.
One thing to notice here is the friend function inside ClassA is using the ClassB .
// inside classA
friend int add(ClassA, ClassB);
// forward declaration
class ClassB;
We can also use a friend Class in C++ using the friend keyword. For example,
class ClassB;
class ClassA {
// ClassB is a friend class of ClassA
friend class ClassB;
... .. ...
};
27 | P a g e
class ClassB {
... .. ...
}
When a class is declared a friend class, all the member functions of the friend
class become friend functions.
Since classB is a friend class, we can access all members of classA from
inside classB .
#include <iostream>
using namespace std;
// forward declaration
class ClassB;
class ClassA {
private:
int numA;
public:
// constructor to initialize numA to 12
ClassA() : numA(12) {}
};
class ClassB {
private:
int numB;
public:
// constructor to initialize numB to 1
ClassB() : numB(1) {}
28 | P a g e
ClassA objectA;
return objectA.numA + numB;
}
};
int main() {
ClassB objectB;
cout << "Sum: " << objectB.add();
return 0;
}
Output
Sum: 13
1. #include <iostream>
2. using namespace std;
3. class Employee {
4. public:
5. int id; //data member (also instance variable)
6. string name; //data member(also instance variable)
7. float salary;
8. Emyploee(int id, string name, float salary)
9. {
10. this->id=id;
Name=name;
Salary=salary;
11. this->id = id;
12. this->name = name;
13. this->salary = salary;
14. }
29 | P a g e
15. void display()
16. {
17. cout<<id<<" "<<name<<" "<<salary<<endl;
18. }
19. };
20. int main(void) {
21.
22. Employee e1 =Employee(101, "Sonoo", 890000); //creating an object of Employee
23. Employee e2=Employee(102, "Nakul", 59000); //creating an object of Employee
24. e1.display();
25. e2.display();
26.
27. return 0;
28. }
Output:
C++ static
In C++, static is a keyword or modifier that belongs to the type not instance. So instance is
not required to access the static members. In C++, static can be field, method, constructor,
class, properties, operator and event.
t is used to refer the common property of all objects such as rateOfInterest in case of
Account, companyName in case of Employee etc.
30 | P a g e
1. #include <iostream>
2. using namespace std;
3. class Account {
4. public:
5. int accno; //data member (also instance variable)
6. string name; //data member(also instance variable)
7.
8. static float rateOfInterest;
9.
10. Account(int accno, string name)
11. {
12. this->accno = accno;
13. this->name = name;
14. }
15. void display()
16. {
17. cout<<accno<< "<<name<< " "<<rateOfInterest<<endl;
18. }
19. };
20. float Account::rateOfInterest=6.5;
21. int main(void) {
22.
23. Account a1 =Account(201, "Sanjay"); //creating an object of Employee
24. Account a2=Account(202, "Nakul"); //creating an object of Employee
25. a1.display();
26. a2.display();
27.
28. return 0;
29. }
Output:
1. #include <iostream>
2. using namespace std;
3. class Account {
4. public:
5. int accno; //data member (also instance variable)
6. string name;
7. static int count;
8. Account(int accno, string name)
9. {
10. this->accno = accno;
31 | P a g e
11. this->name = name;
12. count++;
13. }
14. void display()
15. {
16. cout<<accno<<" "<<name<<endl;
17. }
18. };
19. int Account::count=0;
20. int main(void) {
21. Account a1 =Account(201, "Sanjay"); //creating an object of Account
22. Account a2=Account(202, "Nakul");
23. Account a3=Account(203, "Ranjana");
24. a1.display();
25. a2.display();
26. a3.display();
27. cout<<"Total Objects are: "<<Account::count;
28. return 0;
29. }
Output:
201 Sanjay
202 Nakul
203 Ranjana
Total Objects are: 3
32 | P a g e