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

Chapter 3 - Object Oriented Programming

The document discusses object-oriented programming concepts like classes, objects, constructors, and encapsulation. It provides examples in C++ to illustrate these concepts. Specifically, it shows: 1) A Circle class definition with private data member radius and public getArea() method. It demonstrates object creation and accessing members. 2) Another example showing how a default constructor initializes radius when no value is passed. 3) A third example overloading the Circle constructor to allow initializing radius via an argument.

Uploaded by

shabir Ahmad
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
78 views

Chapter 3 - Object Oriented Programming

The document discusses object-oriented programming concepts like classes, objects, constructors, and encapsulation. It provides examples in C++ to illustrate these concepts. Specifically, it shows: 1) A Circle class definition with private data member radius and public getArea() method. It demonstrates object creation and accessing members. 2) Another example showing how a default constructor initializes radius when no value is passed. 3) A third example overloading the Circle constructor to allow initializing radius via an argument.

Uploaded by

shabir Ahmad
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 110

Applied Programming

(Object-Oriented Programming)
(CS 319)

Department of Computer Science


National University of Computer & Emerging Sciences,
Islamabad Campus
Why Objects?
But binary is hard (for humans) to work with…
Object-oriented Programming (OOP)

• Object-oriented programming approach organizes


programs in a way that mirrors the real world, in
which all objects are associated with both attributes
and behaviors

• Object-oriented programming involves thinking in


terms of objects

• An OOP program can be viewed as a collection of


cooperating objects
Classes
Classes in OOP
 Classes are constructs/templates that define
objects of the same type.

 A class uses variables to define data fields


 functions to define behaviors.

 Additionally, a class provides a special type of


function, known as constructors,
 Invoked to construct objects from the class.
Objects in OOP
 An object has a unique identity, state, and behaviors.

 The state of an object consists of a set of data fields


(also known as properties) with their current values.

 The behavior of an object is defined by a set of


functions
Class and Object
• A class is template that defines what an object’s
data and function will be.

• An object is an instance of a class (the terms


object and instance are often interchangeable).
UML Diagram for Class and Object
Circle Class name

radius: double Data fields

Circle() Constructors and Methods


Circle(newRadius: double)
getArea(): double

circle1: Circle circle2: Circle circle3: Circle

radius: 10 radius: 25 radius: 125


Class in C++ - Example
Class in C++ - Example
class Circle
{
public:
// The radius of this circle
Note:
double radius; Data field the special syntax
for constructor
// Construct a circle object
Circle() (no return type!)
{
radius = 1;
Constructors
}

// Construct a circle object


Circle(double newRadius)
{
radius = newRadius;
}

// Return the area of this circle


double getArea() Function
{
return radius * radius * 3.14159;
}
};
Class is a Type
• You can use primitive data types to define
variables.

• You can also use class names to declare object


names.

• In this sense, a class is an abstract data-type or


user-defined data type.
Class Data Members and Member Functions

• The data items within a class are


called data members or data fields
or instance variables

• Member functions are functions that


are included within a class. Also
known as instance functions.
Object Creation - Instantiation
• In C++, you can assign a name when creating an object.

• A constructor is invoked when an object is created.

• The syntax to create an object using the no-arg


constructor is

ClassName objectName;

• Defining objects in this way means creating them. This is


also called instantiating them.
A Simple Program – Object Creation
class Circle
{ C1 Object Instance
private:
double radius;
public: : C1
Circle()
{ radius = 5.0; } radius: 5.0
double getArea( )
{ return radius * radius * 3.14159; }
Allocate memory
}; for radius

void main()
{
Circle C1;
//C1.radius = 10; can’t access private member outside the class
cout<<“Area of circle = “<<C1.getArea( );
}
Constructors
 A constructor in a class is a special function used to create an
object. Constructor has exactly the same name as the defining
class

 Constructors can be overloaded (i.e., multiple constructors


with different signatures) [Purpose: making it easy to
construct objects with different initial data values).

 A class may be declared without constructors. In this case, a


no-argument constructor with an empty body is implicitly
declared in the class known as default constructor

 Note: Default constructor is provided automatically only if no


constructors are explicitly declared in the class.
Constructors’ Properties

 Constructors must have the same name as the class


itself.

 Constructors do not have a return type—not even void.

 Constructors play the role of initializing objects.


Object Member Access Operator
• After object creation, its data and functions can be
accessed (invoked) using:
– the (.) operator, also known as the object member
access operator.

• objectName.dataField references a data field in the


object

• objectName.function( ) invokes a function on the object


A Simple Program – Accessing Members
class Circle
{ C1 Object Instance
private:
double radius;
public: : C1
Circle()
{ radius = 5.0; } radius: 5.0
double getArea()
{ return radius * radius * 3.14159; }
Allocate memory
}; for radius

void main( )
{
Circle C1;
//C1.radius = 10; can’t access private member outside the class
cout<<“Area of circle = “<<C1.getArea();
}
Access Modifiers
• Access modifiers are used to set access levels for
classes, variables, methods, and constructors
• private, public, and protected
• In C++, default accessibility is private
Data Hiding - Data Field Encapsulation
• A key feature of OOP is data hiding
– data is concealed within a class so that it cannot be
accessed mistakenly by functions outside the class.

• To prevent direct modification of class attributes


(outside the class), the primary mechanism for hiding
data is to put it in a class and make it private using
private keyword. This is also known as data field
encapsulation.
Hidden from Whom?

• Data hiding means hiding data from parts of the


program that don’t need to access it. More
specifically, one class’s data is hidden from other
classes.

• Data hiding is designed to protect well-intentioned


programmers from mistakes.
A Simple Program – Accessing Member Function
class Circle
{ C1 Object Instance
private:
double radius;
public: : C1
Circle()
{ radius = 5.0; } radius: 5.0
double getArea()
{ return radius * radius * 3.14159; }
Allocate memory
}; for radius

void main()
{
Circle C1;
//C1.radius = 10; can’t access private member outside the class
cout<<“Area of circle = “<<C1.getArea();
}
A Simple Program – Default Constructor
class Circle
{ C1 Object Instance
private:
double radius;
public:
//Default Constructor : C1
Circle()
//
{ No Constructor
} Here
radius: Any Value
double getArea()
{ return radius * radius * 3.14159; }
};
Allocate memory
for radius

void main()
{
Circle C1;
//C1.radius = 10; can’t access private member outside the class
cout<<“Area of circle = “<<C1.getArea();
}
Object Construction with Arguments

 The syntax to declare an object using a constructor with


arguments is:

ClassName objectName(arguments);

 For example, the following declaration creates an object


named circle1 by invoking the Circle class’s constructor
with a specified radius 5.5.

Circle circle1(5.5);
A Simple Program – Constructor with Arguments
class Circle
{ C1 Object Instance
private:
double radius;
public: : C1
Circle(double rad)
{ radius = rad; } radius: 9.0
double getArea()
{ return radius * radius * 3.14159; }
Allocate memory
}; for radius

void main()
{
Circle C1(9.0);
//C1.radius = 10; can’t access private member outside the class
cout<<“Area of circle = “<<C1.getArea();
}
Output of the following Program?

class Circle
{
private:
double radius;
public:
Circle(double rad)
{ radius = rad; }
double getArea()
{ return radius * radius * 3.14159; }
};

void main()
{
Circle C1;
cout<<“Area of circle = “<<C1.getArea();
}
Constructor Overloading
class Circle
{
private:
double radius;
public:
Circle ()
{ radius = 1; }
Circle(double rad)
{ radius = rad; }
double getArea()
{ return radius * radius * 3.14159; }
};
void main()
{
Circle C2(8.0);
Circle C1;
cout<<“Area of circle = “<<C1.getArea();
}
The this Pointer
 this keyword is a special built-in pointer that references
to the calling object.

 The this pointer is passed as a hidden argument to all


non-static member function calls and is available as a
local variable within the body of all non-static functions.

 Can be used to access instance variables within


constructors and member functions
Without this Pointer
class Circle
{
private:
double radius;
public:
Circle(double rad)
{ radius = rad; }
double getArea()
{ return radius * radius * 3.14159; }
};

void main()
{
Circle C1(99.0);
cout<<“Area of circle = “<<C1.getArea();
}
The this Pointer
class Circle
{
private:
double radius;
public:
Circle(double radius)
{ this->radius = radius; }
double getArea()
{ return radius * radius * 3.14159; }
};

void main()
{
Circle C1(99.0);
cout<<“Area of circle = “<<C1.getArea();
}
Other use of this Pointer
class Circle
{
private:
double radius;
public:
Circle(double radius)
{ this->radius = radius; }
double getArea( )
{ return this->radius * this->radius * 3.14159; }
};

void main()
{
Circle C1(99.0);
cout<<“Area of circle = “<<C1.getArea();
}
Member Functions
Separating Declaration from Implementation
• C++ allows to separate class declaration from
implementation

• Class declaration describes the contract of the class and


the class implementation implements the contract

• The class declaration simply lists all data fields,


constructor prototypes, and the functions

• The class implementation implements the constructors


and functions
Member Functions
Separating Declaration from Implementation
class Circle
{
private:
double radius;
public:
Circle(double radius)
{ this->radius = radius; }
double getArea( ); // Not implemented yet
};
double Circle::getArea()
{ return this->radius * radius * 3.14159; }
void main()
{
Circle C1(99.0);
cout<<“Area of circle = “<<C1.getArea();
}
const Member Functions
class Example
{
private:
int var1;
int var2; void main()
public: {
Example(int var1, int var2) Example ex1(10, 60);
{ this->var1 = var1; Example ex2(170, 30);
this->var2 = var2; ex1.show();
} ex2.show();
void show() const }
{ cout<<“var1 = “<<this->var1;
cout<<“var2 = “<< this->var2;
// var1 = 90;
// var2 = 50;
}
};
Lecture objectives
• To learn how to create objects with new
• To learn the use of destructor
• To study constructor initializer list
• To study accessor and mutator methods
• To see the working of Default copy constructor and
Member-wise Copy
• To learn the scope of variables
A Simple Program – Object Creation
class Circle C1 Object Instance
{
private: : C1

double radius; ra d iu s : 5 .0

Allocate memory
public: for radius

Circle() C2 Object Instance


{ radius = 5.0; }
double getArea() : C2

{ return radius * radius * 3.14159; } r a d i u s : 5 .0

}; Allocate memory
for radius

void main()
{
Circle c1;
Circle *c2 = new Circle();
cout<<“Area of circle = “<<c1.getArea()<<c2->getArea();
}
Destructors
• A destructor is a member function with the same
name as its class prefixed by a ~ (tilde).

• Destructors are usually used to de-allocate memory


and do other cleanup for a class object and its class
members when the object is destroyed.

• A destructor takes no arguments and has no return


type.

• Destructors cannot be declared const, volatile, static.


A destructor can be declared virtual or pure virtual.
Destructor

• If no user-defined destructor exists for a class and one


is needed, the compiler implicitly declares a
destructor:
This implicitly declared destructor is a public
member of its class.
Destructor - Example
Class
class Circle declaration
{
private: void main()
double radius; {
public: Circle c1;
Circle(); Circle *c2 = new Circle(10.7);
Circle(double); cout<<“Area of circle = “<<c1.getArea();
double getArea(); cout<<“Area of circle = “<<c2->getArea();
~Circle(); }
};
Circle::Circle()
{ radius = 1.0; }
Circle::Circle(double rad)
{ radius = rad; } Class
double Circle::getArea() Implementation
{ return radius * radius * 3.14; }
Circle::~Circle() { cout<<“Destructor called”; }
Constructor Initializer

Circle(): radius(1) Circle()


{ Same as {
} radius = 1;
}
(a) (b)
Member Initialization List
• One task of the Constructor is to initialize data members:
Circle( ) { radius = 1.0; }
But it is not preferred approach. The preferred approach is:
Circle( ): radius(1.0)
{ }

• If multiple members be to initialize, separate them by


commas. The result is the initializer list (also known as
member-initialization list)
Circle( ): radius(1.0), area(0.0)
Member
{ } Initialization List
Reasons for Constructor Initializers
• In the initializer list, members initialized with given
values before the constructor even starts to execute

• This is important in some situations e.g. the initializer


list is the only way to initialize const member data
Reasons for Constructor Initializers
Accessor (getter) and Mutator (Setter) Functions
• A get function is referred to as a getter (or accessor),
• A set function is referred to as a setter (or mutator).

• A get function has the following header:


returnType getPropertyName() { }

• A set function has the following header:


void setPropertyName(dataType propertyValue) { }
Example
class Book{
private:
int bookID, totalPage;
float price;
public:
Book():bookID(0),totalPage(0),price(0.0) Mutator
{ } Functions
(i.e., setter)
void setBookID(int bid){ bookID = bid; }
void setPages (int pn){ totalPage = pn; }
void setPrice(float p){ price = p; }

int getBookID(){ return bookID; } Accessor


Functions
int getPages(){ return totalPages; } (i.e., getters)
float getPrice(){ return price; }
};
Default copy constructor
A type of constructor that is used to initialize an
object with another object of the same type is
known as default copy constructor.

 It is by default available in all classes

 syntax is ClassName(ClassName &Variable)


Default Copy Constructor - Example
class Distance {
private:
int feet; float inches;
public:
Distance( ):feet(0),inches(0.0)
{ }
Distance(int ft, float in): feet(ft), inches(in)
{ }
Distance(Distance &d)
{ feet = d.feet; inches = d.inches; } void main() {
Distance dist1(11,22.8);
void showDistance() Distance dist2(dist1);
{ Distance dist3 = dist1;
cout<<“Feet = “<<feet; dist1.showDistance();
cout<<“Inches=“<<inches;
dist2.showDistance();
}
}; dist3.showDistance();
}
Memberwise Copy
 Another different format has exactly the same
effect, causing object to be copied member-by-
member into other object.

 Remember, object1 = object2 will not invoke the


copy constructor. However, this statement is legal
and simply assigns the values of object2 to object1,
member-by-member.
This is the task of the overloaded assignment
operator (=).
Memberwise Copy - Example
class Distance
{
private:
int feet; float inches;
public:
Distance():feet(0),inches(0.0)
void main()
{ } {
Distance(int ft, float in): feet(ft), inches(in) Distance dist1(11,22.8);
{ } Distance dist2(dist1);
void showDistance() Distance dist3 = dist1;
Distance dist4;
{ dist4 = dist1;
cout<<“Feet = “<<feet; dist1.showDistance();
cout<<“Inches=“<<inches; dist2.showDistance();
} dist3.showDistance();
dist4.showDistance();
}; }
Returning Objects from Function - Example
class Distance {

public:
int feet;
Distance():feet(0)
{ } void main()
Distance(int ft): feet(ft) {
{ } Distance dist1, dist3;
Distance addDist(Distance d) Distance dist2(11);
{ dist3 = dist1.addDist(dist2);
dist1.showDistance();
Distance temp;
dist2.showDistance();
temp.feet = this->feet + d.feet; dist3.showDistance();
return temp; }
}
void showDistance()
{ cout<<“Feet = “<<feet; }
};
Accessing Object Members via Pointers

• Complete and Shorthand Member selection operator


for accessing object members. For example:

Circle circle1;
Circle *pCircle = &circle1;
cout << "The radius is " << (*pCircle).radius << endl;
cout << "The area is " << (*pCircle).getArea( ) << endl;
pCircle->radius = 5.5;
cout << "The radius is " << pCircle->radius << endl;
cout << "The area is " << pCircle->getArea( ) << endl;
Passing Objects to Functions
 Three ways
1. Pass objects by value
2. Pass objects by reference
3. Pass objects by reference via pointers
Pass by value
class Circle {
private:
double radius;
public: void main()
Circle(); {
Circle(double); Circle myCircle;
double getArea(); printCircle(myCircle);
}; }
Circle::Circle()
{ radius = 1.0;}
double Circle::getArea()
{ return radius * radius * 3.14; }
void printCircle(Circle c)
{ cout<<“the area = “<<c.getArea(); }
Pass by reference
class Circle {
private:
void main()
double radius;
{
public:
Circle myCircle;
Circle();
printCircle(myCircle);
Circle(double);
}
double getArea();
};
Circle::Circle()
{ radius = 1.0;}
double Circle::getArea()
{ return radius * radius * 3.14; }
void printCircle(Circle &c)
{ cout<<“the area = “<<c.getArea(); }
Pass by Reference via pointer
class Circle {
private:
double radius; void main()
public: {
Circle(); Circle myCircle;
Circle(double); printCircle(&myCircle);
double getArea(); }
};
Circle::Circle()
{ radius = 1.0;}
double Circle::getArea()
{ return radius * radius * 3.14; }
void printCircle(Circle *c)
{ cout<<“the area = “<<c->getArea(); }
Copy Constructors
• Each class may define several overloaded constructors and one
destructor.
• Additionally, every class has a copy constructor. The signature
of the copy constructor is:
ClassName (ClassName &)
For example, the copy constructor for the Circle class is
Circle(Circle &)
• The copy constructor can be used to create an object
initialized with another object’s data.
Shallow Copy vs. Deep Copy

The default copy constructor or assignment operator for


copying objects performs a shallow copy, rather than a
deep copy.

In shallow copy, if a data field in a class is a pointer, the


address of the pointer is copied rather than its contents.

In deep copy, if a data field in a class is a pointer, the


contents of that objects are copied rather than its
reference.
Customizing Copy Constructor

 Thedefault copy constructor or assignment


operator = performs a shallow copy.

 To perform a deep copy, you have to implement


the copy constructor.
Shallow Copy - Example
class Test void main()
{ {
private: Test t1(5,10);
int i; Test t2(t1);
int *p;
public: t1.setVal(20,30);
Test(int x, int y)
{ i = x; t1.show();
p = new int(y); t2.show();
} }

void setVal(int x, int y)


{ i = x; *p = y; }

void show()
{
cout<<"i = "<<i<<endl;
cout<<"p = "<<*p<<endl;
}
};
Shallow Copy - Example
class Test{ void main()
private: {
int i; Test t1(1,12);
int *p; Test t2(t1);
public:
Test(int x, int y){ t1.setVal(0,70);
i = x;
p = new int(y); t1.show();
} t2.show();
}
Test(Test &t) {
i = t.i;
p = t.p;
}
void setVal(int x, int y)
{ i = x; *p = y; }
void show() {
cout<<"i = "<<i<<endl;
cout<<"p = "<<*p<<endl;
}
};
Deep Copy - Example
class Test{ void main()
private: {
int i; Test t1(5,1);
int *p; Test t2(t1);
public:
Test(int x, int y){ t1.setVal(90,3);
i = x;
p = new int(y); t1.show();
} t2.show();
}
Test(Test &t) {
i = t.i;
p = new int(*t.p);
}
void setVal(int x, int y)
{ i = x; *p = y; }
void show() {
cout<<"i = "<<i<<endl;
cout<<"p = "<<*p<<endl;
}
};
Deep Copy - Example
class Test{ void main()
private: {
int i; int *p; Test t1(5,1);
public: Test t2(t1);
Test(int x, int y){
i = x; p = new int(y); t1.setVal(90,3);
}
Test(Test &t) t1.show();
{ i = t.i; t2.show();
p = new int(*t.p); }
}
void setVal(int x, int y)
{ i = x; *p = y; }
void show() {
cout<<"i = "<<i<<endl;
cout<<"p = "<<*p<<endl;
}
~Test()
{ delete p;
cout<<“ pointer deleted”;
}
};
Instance and Static Members
instantiate Memory
circle1

radius = 1 1 radius
Circle numberOfObjects = 2
-radius: double
-numberOfObjects: int
2 Number of Objects
+getNumberOfObjects(): int
instantiate
+getArea(): double circle2
radius = 5 radius
5
numberOfObjects = 2
UML Notation:
+: public variables or functions
-: private variables or functions
underline: static variables or functions
Example – Non-Static data members

class Test{ void main()


private: {
int count; Test t1, t2, t3;
public: t1.IncrementCounter();
Test() t2.IncrementCounter();
{ t3.IncrementCounter();
count = 0;
} t1.show();
void IncrementCounter() t2.show();
{ count++; } t3.show();
void show() }
{ cout<<count<<endl; }
};
Example – Static data members
class Test{ void main()
private: {
static int count; Test t1, t2, t3;
static const int y= 6; t1.IncrementCounter();
public: t2.IncrementCounter();
Test() t3.IncrementCounter();
{
// count = 0; t1.show();
} t2.show();
void IncrementCounter() t3.show();
{ count++; } }

void show()
{ cout<<count<<endl; }
};
int Test::count = 0;
Example – Static data members
class Test{ void main()
private: {
static int count; Test t1, t2, t3;
Static function of a class in C++t1.IncrementCounter();
public: cannot access non-
Test()variables, but, it can access
static t2.IncrementCounter();
static variable
{
only. However, non-static member t3.IncrementCounter();
function can
access// static
count and
= 0; non-static variable both.
} Test::show();
void IncrementCounter() Test::show();
{ count++; } Test::show();
}
static void show()
{ cout<<count<<endl; }
};
int Test::count = 0;
Invoking Static Member Function - Syntax

• Use ClassName::functionName(arguments) to invoke a


static function

•and ClassName::staticVariable to access static data


Immutable Objects and Classes

• If the contents of an object cannot be changed


once the object is created, the object is called
an immutable object and

• if a class provides no setter or mutator


functions, then this class is called an immutable
class.
Immutable Classes
For a class to be immutable:
 It must mark all data fields private

 It must not provide any mutator functions and

 No accessor functions that would return a reference or


pointer to a mutable data fields

 Preventing changes in data members from a member


function by making member function constant: const
function
const Member Functions
A const member function guarantees that it will never
modify any of its class’s member data
class Test
{
private:
int alpha;
public:
void nonFunc() //non-const member function
{ alpha = 99; } //OK
void conFunc() const //const member function
{ alpha = 99; } //ERROR: can’t modify a member
};
const Object

• When an object is declared as const, you can’t


modify it.

• It follows that you can use only const member


functions with it, because they’re the only ones
that guarantee not to modify it.
const Object - Example
class Distance
{ void main()
private:
{
int feet; int inches;
const Distance dist1;
public:
Distance():feet(0)
//cout<<dist1.getDistance();
{ }
// Error: getDistance not constant
Distance(int ft): feet(ft)
cout<<dist1.showDistance();
{ }
}
int getDistance()
{
//showDistance() is ok because it is
cout<<“Enter Distance”;cin>>feet;
constant function
}
void showDistance() const
{ cout<<“Feet = “<<feet;
cout<<“Inches=“<<inches;
}
};
Inheritance and Polymorphism
Inheritance – Introduction
• Perhaps the most powerful feature of OOP

• New classes are created from existing classes

• New classes absorb all features of existing classes


including their data and functions.

• Also enhance them by adding their own new
features in form of new data members and new
member functions
Inheritance – Terminology
• Existing classes are called base classes

• New classes are called derived classes

• Objects of derived classes are more specialized as


compared to objects of their base classes
Inheritance Limitations in C++

• All data members (but not private) and


member functions of base class are inherited
to derived class

• Constructors, destructors and = operator are


not inherited
Base Classes and Derived Classes
• A class can be derived from one or more than one classes,
(single as well as multiple base classes).
Syntax
• To define a derived class, we use a class derivation list to
specify the base class(es):

class derived-class: access-specifier base-class

• Where access-specifier is one of public, protected, or


private.

NOTE: If the access-specifier is not used, then it is private by


default.
Constructor and Destructor Chaining
• Constructors are invoked in the order of the following chain
(inheritance chain):
Derived Class  Base Class  Base Class

and executed in the order of the following chain:


Derived Class  Base Class  Base Class

• A base class constructor is executed before the derived class


constructor.

• Conversely, the destructors are automatically invoked+executed


in reverse order, with the derived class’s destructor invoked first.
Derived Class  Base Class  Base Class

• This is called constructor and destructor chaining.


Constructing and Destructor Chaining - Example
class Person {
public:
Person() void main()
{ cout << "Person's constructor \n" ; }
~Person() {
{ cout << "Person's destructor \n" ; } Faculty faculty;
}; }
class Employee: public Person{
public:
Employee()
{ cout << "Employee's constructor \n" ; }
~Employee()
{ cout << "Employee's destructor \n " ; }
};
class Faculty: public Employee{
public:
Faculty()
{ cout << "Faculty's constructor \n "; }
~Faculty()
{ cout << "Faculty's destructor \n"; }
};
Explicitly Invoking Base Class Constructors
Unlike data fields and functions, the constructors of a base class are
not inherited in the derived class.
Base class constructors can only be invoked from the constructors of
the derived classes to initialize the data fields in the base class. The
syntax to invoke it is as follows:

DerivedClass(parameterList): BaseClass()
{ // Perform initialization }

DerivedClass(parameterList): BaseClass(argumentList)
{ // Perform initialization }
No-Arg Constructor in Base Class
A constructor in a derived class must always invoke a constructor in
its base class. If a base constructor is not invoked explicitly, the base
class’s no-arg constructor is invoked by default. For example,

Circle() Circle(): GeometricObject()


{ is equivalent to {
radius = 1; radius = 1;
} }

Circle(double radius) Circle(double radius)


{ is equivalent to : GeometricObject()
this->radius = radius; {
this->radius = radius;
} }

Constructors of ONLY direct base class can be invoked


The protected Keyword

 A protected data field or a protected function in a


base class can be accessed by name in its derived
classes (not with the object of the derived class).
The protected Keyword

 A protected member is accessible from within the class


in which it is declared, and from within any class
derived from the class that declared it.

 A protected member of a base class is accessible in a


derived class only (not with the object of the derived
class)
Find Errors
class Base{ void main()
protected: int y; {
private: int x; Derived d;
public: int z; cout<<d.x;
Base( ) cout<<d.y;
{ x = 0; y = 0; z = 0; } cout<<d.z;
}; }
class Derived: public Base{
public:
void showX(){ cout<<"x = "<<x; }
void showY(){ cout<<"y = "<<y; }
void showZ(){ cout<<"z = "<<z; }
};
Find Errors
class Base{ void main()
protected: int y; {
private: int x; Derived d;
public: int z; //cout<<d.x;
Base( ) //cout<<d.y;
{ x = 0; y = 0; z = 0; } cout<<d.z;
}; }
class Derived: public Base{
public:
void showX(){ /*cout<<"x = "<<x;*/}
void showY(){ cout<<"y = "<<y; }
void showZ(){ cout<<"z = "<<z; }
};
Types of Inheritance specified by Access Specifiers
• 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 specified by Access Specifier
class A {
public: int x;
protected: int y;
Public, Private, and
private: int z; Protected Inheritance
};
class B : public A
{
// x remains public and accessible here
// y remains protected and accessible here
// z remains private and is not accessible here
};
class C : protected A
{
// x becomes protected and accessible here
// y remains protected and accessible here
// z remains private and is not accessible here
};
class D : private A
{
// x becomes private, accessible here but not in subclasses of class D
// y becomes private, accessible here but not in subclasses of class D
// z remains private and is not accessible here
};
Function Overloading and Function Overriding

• Overloading a function is a way to provide more


than one function with the same name but with
different signatures to distinguish them.

• In function overriding (redefine a function), the


function must be defined in the derived class
using the same signature and same return type
as in its base class.
Virtual Functions
• A virtual function is a member function that you expect
to be redefined in derived classes.

• When you refer to a derived class object using a pointer


to the base class, (you can call a virtual function for that
object and execute the derived class's version of the
function).

• Virtual functions ensure that the correct function is


called for an object

• The keyword virtual tells compiler that it should not


perform early binding
Function Overriding and Polymorphism

• In C++, redefining a virtual function in a derived class is


called overriding a function.

• Polymorphism is a mechanism that allows you to


implement a function in different ways

• One of the key features of derived classes is that a


pointer to a derived class is type-compatible with a
pointer to its base class.
Need for Polymorphism – Example (1)
class Base{
public: void main()
void show() {
{ cout<<"Base\n"; }
Base b;
};
Derv1 d1;
class Derv1:public Base{ Derv2 d2;
public:
void show() b.show();
{ cout<<"derv1\n"; } d1.show();
}; d2.show();

class Derv2:public Base{ b = d1;


public:
b.show();
void show()
{ cout<<"derv2\n"; }
}; b = d2;
b.show();
}
Need for Polymorphism – Example (2)
class Base{
public: void main()
void show() {
{ cout<<"Base\n"; }
Base* b;
};
Derv1 d1;
class Derv1:public Base{ Derv2 d2;
public:
void show() b = &d1;
{ cout<<"derv1\n"; } b->show();
};
b = &d2;
class Derv2:public Base{ b->show();
public:
void show()
}
{ cout<<"derv2\n"; }
};
Polymorphism
class Base{
public: void main()
virtual void show() {
{ cout<<"Base\n"; } Base* b;
};
Derv1 d1;
Derv2 d2;
class Derv1:public Base{
public:
void show() b = &d1;
{ cout<<"derv1\n"; } b->show();
};
b = &d2;
class Derv2:public Base{ b->show();
public:
void show()
}
{ cout<<"derv2\n"; }
};
Define Virtual Functions – Enable Dynamic Binding

To enable dynamic binding for a function, you need to do


two things:

1. The function must be declared virtual in the base class.

2. The variable that references the object for the function


must contain the address of the object.
– Use pointer of base class to hold address of derived
class objects.
No Dynamic Binding with Reference Variable
class Base{
public: void main()
virtual void show() {
{ cout<<"Base\n"; }
Base b;
};
Derv1 d1;
class Derv1:public Base{ Derv2 d2;
public:
void show() b.show();
{ cout<<"derv1\n"; }
}; b=d1;
b.show();
class Derv2:public Base{
public:
b=d2;
void show()
b.show();
{ cout<<"derv2\n"; }
}; }
Note:
If a function is defined virtual in a base class, it is
automatically virtual in all its derived classes. It is
not necessary to add the keyword virtual in the
function declaration in the derived class.
When to use virtual functions?

 If a function defined in a base class needs to be


redefined in its derived classes, you should declare it
virtual to avoid confusions and mistakes.

 On the other hand, if a function will not be redefined, it


is more efficient without declaring it virtual, because it
takes more time and system resource to bind virtual
functions dynamically at runtime.
Abstract Classes and Pure Virtual Functions
 In the inheritance hierarchy, classes become more specific
and concrete with each new derived class.

 If you move from a derived class back up to its parent and


ancestor classes, the classes become more general and less
specific.

 Class design should ensure that a base class contains


common features of its derived classes.

 Sometimes a base class is so abstract that it cannot have any


specific instances. Such a class is referred to as an abstract
class.

 For a class to be an abstract class, it must contain at least


one pure virtual function.
Abstract Classes and Pure Virtual Functions

 Pure virtual function (e.g., Show()) can be declared as:

virtual void show( ) = 0;

 Once you’ve placed a pure virtual function in the base


class, you must override it in all derived classes from
which you want to instantiate objects.

 If a class does not override the pure virtual function, it


becomes an abstract class itself.

 It is not possible to instantiate object of abstract class.


Abstract class and Pure Virtual Function - Example
class Base{
public: void main(){
virtual void show() = 0; // Base bs;
};
class Derv1:public Base{ Base *ptr;
public: Derv1 d1;
void show() Derv2 d2;
{
cout<<"derv1\n"; ptr = &d1;
} ptr->show();
};
class Derv2:public Base{ ptr = &d2;
public: ptr->show();
void show() }
{
cout<<"derv2\n";
}
};
Abstract class with Non-Virtual Functions and Members
class Base{
public: void main(){
virtual void show() = 0; // Base bs;
};
class Derv1:public Base{ Base *ptr;
public: Derv1 d1;
void show() Derv2 d2;
{
cout<<"derv1\n"; ptr = &d1;
} ptr->show();
};
class Derv2:public Base{ ptr = &d2;
public: ptr->show();
void show() }
{
cout<<"derv2\n";
}
};
Virtual Destructors

 In C++, classes and class destructors can be virtual but


not constructors.

 If a base class destructor is not virtual then delete,


like a normal member function, calls the destructor
for the base class, not the destructor for the derived
class.
Virtual Destructors
class Base void main()
{ {
public:
~Base() Base *p = new Derv;
{ delete p;
cout<<“ Base Destroyed \n”;
} /*will call destructor of
}; base class not the derived
class*/
class Derv: public Base
{ }
public:
~Derv()
{
cout<<“ Derv Destroyed \n”;
}
};
Virtual Destructors
class Base void main()
{ {
public:
virtual ~Base() Base *p = new Derv;
{ delete p;
cout<<“ Base Destroyed \n”;
} /*will call destructor of
}; derived class and then base
class*/
class Derv: public Base }
{
public:
~Derv()
{
cout<<“ Derv Destroyed \n”;
}
};
Multiple Inheritance
Multiple Inheritance – Syntax
 The base classes from which C is derived are listed following
the colon in C’s specification and are separated by commas

class A
{

};

class B
{

};

class C : public A, public B


{

};
Types of Inheritance

You might also like