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

Lecture Notes 05 (CSI2372 - Advanced Programming Concepts With C++)

C++ notes at the University of Ottawa

Uploaded by

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

Lecture Notes 05 (CSI2372 - Advanced Programming Concepts With C++)

C++ notes at the University of Ottawa

Uploaded by

Yosri Ketata
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

CSI2372 - Advanced Programming Concepts with C++

Instructor: Shahram Moradi


Contact: [email protected]
Office Hours: Tuesday 9:30 to 10:30 AM
Office: Room 344 ARC Building, 25 Templeton St., Ottawa, ON, Canada
Lecture hours: Mondays from 4 pm to 5:20 pm
Quizzes: Every Wednesdays from 2:30 pm to 3:50 pm - Online through Brightspace- Location is optional (home or classroom) – 1st attempt in this time
interval is mandatory and second attempt will have a deadline (lecture quizzes 10% + Lab quizzes 10% + tutorial quizzes 10% = overall 30%) – No lab
assignments
Final exam (40%): All modules covered in the course – Written exam
Midterm1 (15%): 16 October 2023 – Monday at 4 pm to 5:20 pm – Location is optional (home or classroom online) 1 attempt Online through Brightspace
Midterm2 (15%): 15 November 2023 – Wednesday at 2:30-3:50 pm – Location is optional (home or classroom) 1 attempt and Online through Brightspace
Teaching Assistant:
1. Bhattacharjee/Mayukh, email: [email protected]
2. Dai/Lansu, email: [email protected]
3. Emami Afshar/Bahar, email: [email protected]
4. Khare/Akshat, email: [email protected]
5. Kumar/Preyank, email: [email protected]
6. Yathirajulu/Ruchitha, email: [email protected]
7. Keswani /Yash, email: [email protected]

1
CSI2372 - Advanced Programming Concepts with C++
Course Outline:

Throughout this course, we will explore the following topics:


Module 1: Foundations of C++ Programming
• Session 1: Introduction and Contrasting C++ with Java Programming
• Session 2: C++ Data Types and Their Applications
• Session 3: Pointers, Memory Management, and Efficiency
❑ Midterm 1: Assessment covering Sessions 1-3
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
• Session 5: Navigating File and Stream Input/Output in C++
• Session 6: Preprocessor Macros and Their Role
❑ Midterm 2: Assessment covering Sessions 4-6
Module 3: Templates, Computation, and Practical Applications
• Session 7: Harnessing Templates and the Standard Template Library
• Session 8: Numerical Computation Techniques using C++
• Session 9: Interface Integration with Hardware Components
• Session 10: Exploring Engineering Applications
❑ Final Exam: Comprehensive Assessment of All Modules

2
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++

➢ What is OOP?
➢ Key principles of OOP: encapsulation, inheritance, and polymorphism.
➢ Defining classes in C++.
➢ Creating objects from classes.
➢ Member variables and member functions.
➢ Data hiding and access control.
➢ Public, private, and protected access specifiers.
➢ Creating derived classes.
➢ Base class and derived class relationships.
➢ Accessing base class members in derived classes.
➢ Introduction to polymorphism.
➢ Function overloading and overriding.
➢ Virtual functions and dynamic binding.
➢ Constructors and their types.
➢ Destructors and resource management.

3
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++

➢ Abstract classes and pure virtual functions.


➢ Overloading operators to work with user-defined types.
➢ Real-world examples of inheritance and polymorphism.
➢ Design patterns that leverage OOP concepts.
➢ SOLID principles.
➢ Design by Contract.
➢ Composition over inheritance.
➢ Smart pointers and RAII.
➢ Managing object lifetimes.
➢ Handling exceptions in class hierarchies.
➢ Custom exception classes.
➢ Overview of the OOAD process.
➢ UML diagrams for modeling.

4
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ What is OOP?

Object-Oriented Programming (OOP) is a programming paradigm that organizes data and behavior into reusable
`
structures called "objects." Each object combines data (attributes or properties) and the functions (methods) that
operate on that data. OOP promotes the concept of modeling real-world entities as objects to facilitate code
organization and reusability.

Example:
In a simulation game, you can represent a "Player" as an object in OOP. The Player object would have attributes like
"name," "score," and "health," and methods like "move," "attack," and "heal." This allows you to interact with and
manipulate players as self-contained units, making the code more intuitive and maintainable.

5
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Key principles of OOP: encapsulation, inheritance, and polymorphism.

Encapsulation: Encapsulation is an OOP concept that involves bundling data (attributes or


`
properties) and methods (functions) that operate on that data into a single unit, called a class.
The reason for having class is encapsulation which provides:
➢ It restricts direct access to an object's internal state, providing control over how data is
modified and accessed.
➢ Encapsulation helps ensure data integrity and reduces unintended interference with an
object's properties.

6
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Key principles of OOP: encapsulation, inheritance, and polymorphism.

Inheritance: Inheritance is a mechanism in OOP that allows one class (called a subclass or
`
derived class) to inherit the properties and behaviors of another class (called a superclass or
base class). It promotes code reuse and hierarchy, where subclasses can extend or specialize
the functionality of their superclass. Inheritance fosters a relationship between classes,
enabling the creation of a hierarchy of related objects.

7
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Key principles of OOP: encapsulation, inheritance, and polymorphism.

Polymorphism: Polymorphism is the ability of objects to take on different forms based on their
`
context. In OOP, polymorphism allows objects of different classes to be treated as objects of a
common base class. This enables code to be written more generically, as methods can be invoked on
objects without knowing their specific types. Polymorphism is often achieved through method
overriding and interfaces, allowing for flexibility and extensibility in software design.

8
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++.
➢ Defining classes in C++.

In C++, when you define classes, you're essentially creating a blueprint that outlines the structure and
`
behavior of objects. These classes act as templates, encapsulating both properties (data) and methods
(functions) that define how objects of that class will work. Classes allows you to create instances (objects)
based on this template.

https://www.geeksforgeeks.org/c-classes-and-objects/ 9
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Creating objects from classes.

Having CLASS in C++ gives you:

Encapsulation:
` Classes allow you to bundle data (attributes or member variables) and functions (methods) that
operate on that data into a single unit. This encapsulation restricts direct access to the data from outside the class,
promoting data integrity and reducing the risk of unintended modifications.

Abstraction: Classes enable you to define abstract data types. You can hide the implementation details of how data
is stored and processed, providing a clean interface for users of the class. This abstraction simplifies code
maintenance and promotes a clearer understanding of the program's structure.

Modularity: Classes facilitate code modularity by breaking down complex systems into smaller, manageable units.
This modular design makes it easier to work on individual components independently, leading to more maintainable
and scalable code

10
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Member variables and member functions.

Data Members (Attributes): These are variables that store the object's data or state. They define the characteristics
or properties of objects. Data members are private by default, meaning they are accessible only within the class. We
need data`member to:
1. Data Storage
2. Data Encapsulation
3. Information Hiding
Member Functions (Methods): These are functions associated with the class that define its behavior. Member
functions are used to perform operations on the class's data members. They are declared within the class and
defined outside it. We need member functions to:
1. Encapsulation of Behavior
2. Abstraction of Functionality
3. Modularity and Reusability

11
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Data hiding and access control.`

Data hiding and access control are needed for the following reasons:

➢ Security:
` Prevents unauthorized access and modification of data, enhancing the security of a program.

➢ Encapsulation: Encapsulates implementation details, reducing complexity and improving code maintenance.

➢ Data Integrity: Ensures data is accessed and modified through controlled interfaces, maintaining data integrity.

➢ Abstraction: Hides implementation specifics, promoting a higher-level understanding of classes and objects.

➢ Modularity: Supports modular design by limiting direct dependencies and promoting code reusability.

12
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Public, private, and protected access specifiers.

Public: Public declarations are accessible from anywhere, both inside and outside the class. They define the class's
interface, allowing external code to interact with the class and use its functionality.
`
Private: Private declarations are only accessible within the class itself. They hide implementation details and restrict
access from external code, enhancing data security and maintaining encapsulation.
Protected: Protected declarations are similar to private declarations but are accessible to derived (child) classes.
They allow controlled inheritance, enabling child classes to access and manipulate protected members while
keeping them hidden from external code.

13
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Public, private, and protected access specifiers.

Example 1

14
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Public, private, and protected access specifiers.
// Base class (public, private, and protected members)
class BaseClass {public:
// Public member accessible from anywhere
int publicVar;
`
// Constructor (public)
BaseClass() {}
// Public member function (public)
void PublicFunction() {}
private:
// Private member (only accessible within BaseClass)
int privateVar;
// Private member function (only accessible within BaseClass)
void PrivateFunction() {}
protected:
// Protected member (accessible within BaseClass and derived classes)
int protectedVar;
// Protected member function (accessible within BaseClass and derived classes)
void ProtectedFunction() {}
};

15
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Public, private, and protected access specifiers.
// Derived class publicly derived from BaseClass
class DerivedClassPublic : public BaseClass {public:
// Public member accessible from anywhere
int publicVarDerived;
`
// Constructor (public)
DerivedClassPublic() {}
// Public member function (public)
void PublicFunctionDerived() {}
// Access to public members and protected members inherited from BaseClass
// Access to protected members is still protected in the derived class
};
// Derived class privately derived from BaseClass
class DerivedClassPrivate : private BaseClass {public:
// Access to public members and protected members inherited from BaseClass
// All inherited members become private in the derived class
// Access to private members is not possible from outside DerivedClassPrivate
};
// Derived class protectedly derived from BaseClass
class DerivedClassProtected : protected BaseClass {public:
// Access to public members and protected members inherited from BaseClass
// All inherited members become protected in the derived class
16
};
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Public, private, and protected access specifiers.
int main() {
BaseClass baseObj;
DerivedClassPublic publicDerivedObj;
`
DerivedClassPrivate privateDerivedObj;
DerivedClassProtected protectedDerivedObj;
// Access to public members from outside the class
baseObj.publicVar;
// Access to protected members is not possible from outside the class
// Access to private members is not possible from outside the class
// Access to members in derived classes follows the access specified in the derived class
itself
return 0;}

17
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Public, private, and protected access specifiers.

Example 2

18
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Public, private, and protected access specifiers.
#include <iostream>
class Class1 {
public:
int publicVar1;
`
Class1() : publicVar1(0) {}
private:
int privateVar1;
protected:
int protectedVar1;
};
class Class2 {
public:
int publicVar2;
Class2() : publicVar2(0), privateVar2(0), protectedVar2(0) {}
void AddPublicVars(Class1& obj1) {
publicVar2 += obj1.publicVar1;
}

19
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Public, private, and protected access specifiers.
// Note: privateVar2 and protectedVar2 cannot be accessed from Class2.
void PrintVars(Class1& obj1) {
std::cout << "publicVar1 from Class1: " << obj1.publicVar1 << std::endl;
//
` std::cout << "privateVar1 from Class1: " << obj1.privateVar1 << std::endl;
// std::cout << "protectedVar1 from Class1: " << obj1.protectedVar1 << std::endl;
}
private:
int privateVar2;
int protectedVar2;};
int main() {
Class1 obj1;
Class2 obj2;
obj1.publicVar1 = 10;
obj2.publicVar2 = 20;
obj2.AddPublicVars(obj1);
// obj2.AddPrivateVars(obj1); // This will result in a compilation error.
// obj2.AddProtectedVars(obj1); // This will result in a compilation error.
obj2.PrintVars(obj1);
return 0;}

20
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Creating derived classes.
Derived classes allow you to create new classes based on existing ones. These derived classes inherit attributes and
behaviors from their base, or parent, classes. This practice is known as inheritance and is a key feature of C++ and other
object-oriented programming languages.
`
1. Create a Base Class (Parent Class): Start by creating a base class that represents common characteristics or attributes
of vehicles. In this example, we'll call it Vehicle. Define the attributes and methods that all vehicles have.
2. Create a Derived Class (Child Class): Create a derived class, Car, that inherits from the Vehicle class. This class will
represent cars and can have additional attributes and methods specific to cars.
3. Define Constructors: Implement constructors for both the base (Vehicle) and derived (Car) classes to initialize their
attributes.
4. Implement Specific Methods: In the derived class (Car), implement methods that are specific to cars. In this example,
we added a drive method.
5. Create Instances: In the main function, create instances of the derived class (Car) and initialize them with specific
make and model values.
6. Invoke Methods: Call methods on the instances to demonstrate polymorphism, where objects of the derived class
can access both their own methods and inherited methods from the base class.

21
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Base class and derived class relationships.
#include <iostream>#include <string>
// Base class (parent class)
class Vehicle {
public: Vehicle(const
` std::string& make) : make(make) {}
void start() const { std::cout << "Starting the " << make << " vehicle." << std::endl; }
private:std::string make;
};
// Derived class (child class)
class Car : public Vehicle {
public:Car(const std::string& make, const std::string& model) : Vehicle(make), model(model) {}
void drive() const { std::cout << "Driving the " << make << " " << model << " car." << std::endl; }
private: std::string model;
};
int main() {
Car myCar("Toyota", "Camry");
myCar.start();
myCar.drive();
return 0;
}

22
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Base class and derived class relationships.
public: Vehicle(const std::string& make) : make(make) {}
// Define a public constructor for the Vehicle class, which takes a make (a string) as a parameter and
initializes the make member with this value.
`
private:std::string make;
// Declare a private member variable named make of type string

class Car : public Vehicle {


// Create a class called Car that inherits publicly from the Vehicle class.

public:Car(const std::string& make, const std::string& model) : Vehicle(make), model(model) {}


// Implement a public constructor for the Car class that accepts two string parameters, make and model,
and initializes the make member of the Vehicle base class with the provided make parameter and the
model member of the Car class with the model parameter

-----------------------------------main()
Car myCar("Toyota", "Camry"); Create an instance of the Car class named myCar with the make 'Toyota'
and model 'Camry'.

myCar.start(); initiate the 'start' operation on the myCar instance.


23
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Accessing base class members in derived classes.

In object-oriented programming, inheritance is a fundamental concept that allows you to create new classes
(derived or child classes) based on existing classes (base or parent classes). When you create a derived class, you
`
inherit the properties and behaviors of the base class, which include its data members and member functions.
Accessing base class members in derived classes is essential for building hierarchical and reusable code.
Steps to Realize This Topic:
1. Define Base Class: Start by defining a base class (parent class) that contains data members and member
functions. These members may be public, protected, or private, depending on the desired level of encapsulation
and access control.
2. Create Derived Class: Create one or more derived classes (child classes) that inherit from the base class. Use the
colon (:) syntax to specify the inheritance relationship.

24
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Introduction to polymorphism.

❑ Polymorphism is a fundamental concept in object-oriented programming (OOP) that allows objects of different
classes to be treated as objects of a common base class. It enables you to write more flexible and reusable code
`
by providing a way to work with objects in a generic way, without needing to know their specific types.
❑ In C++, polymorphism is primarily achieved through two mechanisms:
1. Function overriding (also known as virtual functions) allows derived classes to provide their own
implementation of a base class function
2. Function overloading enables multiple functions with the same name but different parameters.

25
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Introduction to polymorphism.

`
❑Example of function override: function overriding occurs in the derived
classes Circle and Rectangle when they override the calculateArea()
function from the base class Shape.

26
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Function overloading and overriding.

#include <iostream>
class Shape { // Base class
public:` virtual double calculateArea() const { return 0.0; }
}; // Virtual function for calculating the area FUNCTION OVERRIDING

// Default implementation for shapes


class Circle : public Shape {// Derived class representing a circle

private:double radius;
public:Circle(double r) : radius(r) {} // Override the calculateArea() function
for circles
double calculateArea() const override { return 3.14159265359 * radius *
radius; }
}; // Area formula for a circle

27
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Function overloading and overriding.
// Derived class representing a rectangle
class Rectangle : public Shape {
private:double width; double height;
`
public:Rectangle(double w, double h) : width(w), height(h) {}

// Override the calculateArea() function for rectangles


double calculateArea() const override { return width * height; }
}; // Area formula for a rectangle
int main() { // Create objects of different shapes
Shape* shape1 = new Circle(5.0);
Shape* shape2 = new Rectangle(4.0, 6.0);
// Calculate and display the areas using polymorphism
std::cout << "Area of Circle: " << shape1->calculateArea() << std::endl;
std::cout << "Area of Rectangle: " << shape2->calculateArea() << std::endl;

28
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Introduction to polymorphism.

❑Example of function overload: the Calculator class has two overloaded


`
add functions: one that takes two int parameters and another that takes
two double parameters. When you call the add function with different
types of arguments, the appropriate overloaded version is selected
based on the argument types, demonstrating polymorphism through
function overloading.
29
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Function overloading and overriding.
#include <iostream>
class Calculator {
public:
// Function `to add two integers
int add(int a, int b) {return a + b;}
// Overloaded function to add two doubles
double add(double a, double b) {return a + b;}};

int main() { Calculator calc; //create an instance of the Calculator class named calc
int result1 = calc.add(5, 3); // Calls the int version of add
double result2 = calc.add(2.5, 3.7); // Calls the double version of add
std::cout << "Result 1: " << result1 << std::endl;
std::cout << "Result 2: " << result2 << std::endl;
return 0;}
Question: In the given instances, what specifies the calling process?

30
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Virtual functions and dynamic binding.

In C++, virtual functions and dynamic binding are powerful features that enable runtime polymorphism. They allow
you to call` the appropriate function implementation of a derived class when working with objects through a base
class pointer or reference. This is essential for writing flexible and extensible code. Here's a brief explanation and an
example to illustrate virtual functions and dynamic binding:
Virtual Functions:
• A virtual function is a member function declared in a base class with the virtual keyword.
• Virtual functions are designed to be overridden by derived classes.
• When a virtual function is called through a base class pointer or reference, the specific implementation in the
derived class is invoked at runtime.
Dynamic Binding:
• Dynamic binding is the process of selecting the appropriate function implementation at runtime based on the
actual type of the object.
• It occurs when-> a virtual function is called through a base class pointer or reference.
• Dynamic binding allows for polymorphic behavior, where different objects can respond differently to the same
function call.

31
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Virtual functions and dynamic binding.

❑This next slide codes exemplifies virtual functions and dynamic binding :
`
It defines a base class MathOperation with a pure virtual perform function
and three derived classes (Addition, Subtraction, Multiplication) that
implement this function for specific mathematical operations. Through
dynamic binding, a base class pointer is used to perform operations on
instances of the derived classes, demonstrating polymorphic behavior.

32
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Virtual functions and dynamic binding.
#include <iostream>
class MathOperation {// Base class representing a mathematical operation
public:virtual
` double perform(double operand1, double operand2) const = 0;}; // Virtual function
class Addition : public MathOperation { // Derived class for addition
public:double perform(double operand1, double operand2) const override { return operand1 + operand2;
}};
class Subtraction : public MathOperation {// Derived class for subtraction
public:double perform(double operand1, double operand2) const override { return operand1 - operand2;
}};
class Multiplication : public MathOperation { // Derived class for multiplication
public:double perform(double operand1, double operand2) const override { return operand1 * operand2;
}};
int main() {
MathOperation* operation; // Use dynamic binding to select the operation
operation = new Addition();
std::cout << "5 + 3 = " << operation->perform(5, 3) << std::endl;
operation = new Subtraction();
std::cout << "5 - 3 = " << operation->perform(5, 3) << std::endl;
operation = new Multiplication();
std::cout << "5 * 3 = " << operation->perform(5, 3) << std::endl;
return 0;}
33
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Constructors and their types.

Constructors are special member functions in C++ used for initializing objects of a class. They are automatically
`
called when an object of the class is created. Constructors have the same name as the class and are responsible for
setting up the initial state of an object.
Types of Constructors:
Default Constructor:
• A constructor with no parameters.
• It is automatically generated by the compiler if no constructors are defined.
• Initializes the object with default values (e.g., 0 for integers, empty string for strings).
class MyClass { public:MyClass() {} }; // Default constructor

34
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Constructors and their types.

Parameterized Constructor:
`
• Accepts one or more parameters to initialize an object with specific values.
• Allows customization during object creation.
class Student {
public:Student(const std::string& name, int age) { // Parameterized constructor
//Create a public constructor for the Student class, accepting a name (a string)
and age (an integer) as input parameters
this->name = name;
this->age = age;
} //Set the age member of the current object (this) to the value of the age
parameter passed to the constructor.
private:std::string name;
int age;};

35
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Constructors and their types.

Copy Constructor:
`
• Used for creating a new object as a copy of an existing object.
• Helps avoid shallow copy issues.
class Point {
public:Point(int x, int y) : x(x), y(y) {} // Parameterized constructor
//Create a public constructor for the Point class that takes two integer parameters,
x and y, and initializes the class members x and y with these values
Point(const Point& other) { // Declare a copy constructor for the Point class, which
accepts another Point object other as input
this->x = other.x; //Assign the value of the x member in the current object (this) to
the value of other.x
this->y = other.y;}
private:int x, y;};

36
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Constructors and their types.

Copy Assignment Operator:


`
• Used for assigning the values of one object to another after initialization.
class Complex {
public:Complex& operator=(const Complex& other) { // Copy assignment operator
//Define a public assignment operator operator= that takes another Complex
object other as input and returns a reference to a Complex object
this->real = other.real; //Assign the value of the real member in the current
object (this) to the value of other.real
this->imag = other.imag;
return *this;}
private: double real, imag;};

37
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Destructors and resource management.

Destructor:
• Responsible for cleaning up resources when an object is destroyed (e.g., memory deallocation).
• Named with a tilde (~) followed by the class name.

class FileHandler {
public:
FileHandler(const std::string& filename) { file = open(filename); } // Constructor
//Construct a FileHandler object using a filename as input; this object will then
proceed to open the file associated with the provided name.
~FileHandler() { close(file); }
// Destructor|| can I replace the given destructor with: ~FileHandler() {filec =
close(filename);} ?
private:FILE* file;};

38
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ 10 minute Break

https://www.youtube.com/watch?v=LlZWqkCMdfk

39
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Abstract classes and pure virtual functions.

Abstract classes in C++ are classes that cannot be instantiated on their own and are
designed to be base classes for other classes. They often contain one or more pure
virtual functions, which are declared with the virtual keyword and have no
implementation in the base class. Abstract classes serve as a blueprint for derived
classes to implement their own versions of the pure virtual functions.

40
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Abstract classes and pure virtual functions.

41
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Abstract classes and pure virtual functions.

#include <iostream>
class Recipe {
public:
virtual double ingredientA() const = 0;
virtual double ingredientB() const = 0;
virtual double ingredientC() const = 0;
virtual ~Recipe() {}
};
class Food1 : public Recipe {
public:
double ingredientA() const override {
return 0.4; // Example ratio for
ingredient A in Food1 (sums to 1)
}
double ingredientB() const override {
return 0.3; // Example ratio for
ingredient B in Food1 (sums to 1)
}

42
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Abstract classes and pure virtual functions.

double ingredientC() const override {


return 0.3; // Example ratio for
ingredient C in Food1 (sums to 1)
}
};
class Food2 : public Recipe {
public:
double ingredientA() const override {
return 0.2; // Example ratio for
ingredient A in Food2 (sums to 1)
}
double ingredientB() const override {
return 0.6; // Example ratio for
ingredient B in Food2 (sums to 1)
}
double ingredientC() const override {
return 0.2; // Example ratio for ingredient C in
Food2 (sums to 1)
}};

43
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Abstract classes and pure virtual functions.

int main() {
Food1 food1;
Food2 food2;
std::cout << "Food1 Ingredients:" << std::endl;
std::cout << "Ingredient A: " << food1.ingredientA() << std::endl;
std::cout << "Ingredient B: " << food1.ingredientB() << std::endl;
std::cout << "Ingredient C: " << food1.ingredientC() << std::endl;
std::cout << "\nFood2 Ingredients:" << std::endl;
std::cout << "Ingredient A: " << food2.ingredientA() << std::endl;
std::cout << "Ingredient B: " << food2.ingredientB() << std::endl;
std::cout << "Ingredient C: " << food2.ingredientC() << std::endl;
return 0;}

44
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Overloading operators to work with user-defined types.

In C++, operator overloading allows you to define custom behaviors for operators when used with user-
defined types, such as classes. It enables you to extend the functionality of operators beyond their
default actions for built-in types. This feature is particularly useful for creating more intuitive and
expressive code when working with user-defined objects.
Operator overloading involves defining special member functions for operators in your class, which
determine how these operators should behave when applied to objects of that class. Overloaded
operators can simplify code, improve readability, and make your classes work more naturally with
standard operators.

45
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Overloading operators to work with user-defined types.

Let's consider an example of operator overloading with a custom Complex class


representing complex numbers. We'll overload the + operator to allow the addition of
two Complex objects: This code demonstrates operator overloading for complex
number addition. It allows you to use the + operator to add two Complex objects,
providing a concise and custom way to perform addition for complex numbers.

46
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Overloading operators to work with user-defined types.

#include <iostream>
class Complex {private:
double real;
double imaginary;
public:Complex(double r, double i) : real(r), imaginary(i) {}
// Overloading the addition operator '+'
Complex operator+(const Complex& other) const {
double newReal = real + other.real;
double newImaginary = imaginary + other.imaginary;
return Complex(newReal, newImaginary);
}
void display() const {std::cout << real << " + " << imaginary << "i" << std::endl;}};

47
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Overloading operators to work with user-defined types.

int main() {
Complex num1(3.0, 4.0);
Complex num2(1.0, -2.0);
Complex sum = num1 + num2; // Operator '+' is overloaded here
std::cout << "Sum: ";
sum.display(); // Output: Sum: 4 + 2i
return 0;
}

48
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Real-world examples of inheritance and polymorphism.
`
Inheritance:
• Shapes Hierarchy
• Animal Classification
• Employee Hierarchy
Polymorphism:
• Vehicle Types
• Payment Methods
• Music Player
• Geometric Calculations

❑ Inheritance defines a relationship between classes where one class inherits properties and behaviors from
another, while polymorphism allows objects of different classes to be treated as objects of a common base class,
enabling dynamic method invocation.

49
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Real-world examples of inheritance and polymorphism.

1. Shapes `Hierarchy (Inheritance):


In a computer graphics application, you might have a hierarchy of shape classes (e.g., Circle, Rectangle, Triangle)
that inherit from a common base class (e.g., Shape). Each shape class inherits common properties and methods
(e.g., area calculation), allowing you to work with different shapes interchangeably.
2. Animal Classification (Inheritance):
In biology, the classification of animals into groups like mammals, birds, reptiles, and amphibians follows an
inheritance hierarchy. All animals share common characteristics inherited from a common ancestor, and each group
has its unique traits.
3. Employee Hierarchy (Inheritance):
In human resources software, you may have an inheritance hierarchy for employee classes. For example, a base
class "Employee" can have derived classes like "Manager," "Developer," and "Designer," each inheriting common
attributes like name and ID while adding specialized features.

50
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Real-world examples of inheritance and polymorphism.
4. Vehicle Types` (Polymorphism):
In a transportation system, different vehicle types (e.g., cars, trucks, bicycles) can implement a common interface or base
class called "Vehicle." This allows you to treat various vehicles uniformly, even though they have different
implementations for methods like "accelerate" or "brake."
5. Payment Methods (Polymorphism):
In an e-commerce application, various payment methods like credit cards, PayPal, and cryptocurrencies can implement a
common payment interface. This allows the system to process payments without needing to know the specifics of each
payment method.
6. Music Player (Polymorphism):
In a music player application, different audio formats (e.g., MP3, WAV, FLAC) can be played using polymorphism. All audio
files can be treated as "Playable" objects with a common "play" method, regardless of their underlying format.
7. Geometric Calculations (Polymorphism):
In a CAD (Computer-Aided Design) software, you can perform geometric calculations using polymorphism. Different
geometric shapes can implement a common "calculateArea" method, allowing you to calculate areas irrespective of the
shape type.

51
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Design patterns that leverage OOP concepts.

Design patterns themselves ARE NOT part of any header or library in C++. They are general solutions to common
`
software design problems that can be implemented in your code using object-oriented programming principles. You
would typically implement design patterns in your codebase by creating classes and structures following the specific
patterns' guidelines. However, some libraries and frameworks may provide certain design patterns as part of their
functionality, so you might use those libraries to apply certain patterns more easily. Still, the patterns themselves are
not part of standard C++ headers or libraries; they are design concepts that you implement in your code.Here are some
design patterns that leverage object-oriented programming (OOP) concepts:
Singleton Pattern, Factory Method Pattern, Abstract Factory Pattern, Builder Pattern, Prototype Pattern, Adapter
Pattern, Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, Flyweight Pattern, Proxy Pattern, Chain
of Responsibility Pattern, Command Pattern, Interpreter Pattern.

52
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ SOLID principles.

The SOLID principles are a set of five design principles in object-oriented programming that aim to create more
` and scalable software. Each letter in "SOLID" represents one of these principles:
maintainable

Single Responsibility Principle (SRP): A class should have only one reason to change, meaning it should have only
one responsibility or job.
Open/Closed Principle (OCP): Software entities (classes, modules, functions) should be open for extension but
closed for modification. You should be able to add new functionality without changing existing code.
Liskov Substitution Principle (LSP): Subtypes must be substitutable for their base types without affecting the
correctness of the program. In simpler terms, derived classes should be able to replace their base classes without
causing issues.
Interface Segregation Principle (ISP): Clients should not be forced to depend on interfaces they do not use. It
suggests that you should have smaller, more specific interfaces rather than large, general ones.
Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules. Both should
depend on abstractions. In other words, you should depend on abstractions, not concrete implementations.

53
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Design by Contract.

❑ Design by Contract (DbC) is an approach that formalizes software component expectations and obligations
`
through explicit contracts. These contracts specify what components require from others and what they
guarantee. Key elements of DbC include: 1- Preconditions (conditions for routine execution), 2- Postconditions
(guarantees after completion), 3-Invariants (always-true conditions for classes/modules), and 4- Assertions
(runtime checks).
▪ DbC adopts robust, reliable code by documenting and enforcing these contracts, often with specialized tools,
enhancing code quality and understanding, especially in critical systems.
Let’s review an example to ensure certain conditions are always met during the execution of methods, so we use:
1. Assertions to document and enforce preconditions
2. Invariants for a simple BankAccount class.

54
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Design by Contract.
#include <cassert>
class BankAccount {
public:
`
BankAccount(int initialBalance) : balance(initialBalance) { assert(initialBalance >= 0); } //
Precondition
void deposit(int amount) {
assert(amount > 0); // Precondition
balance += amount;
assert(balance >= 0);
}// Invariant
void withdraw(int amount) {
assert(amount > 0); // Precondition
assert(balance >= amount); // Precondition
balance -= amount;
assert(balance >= 0);
} // Invariant
int getBalance() const { assert(balance >= 0); return balance; } // Invariant
private: int balance;
};

55
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Design by Contract.
BankAccount(int initialBalance) : balance(initialBalance) { assert(initialBalance >= 0); } //
Precondition//Create a BankAccount object with an initial balance, setting the balance member variable
`
to the provided initialBalance value while ensuring that initialBalance is greater than or equal to
zero using the assert statement

assert(amount > 0); // Precondition //Verify that the amount is greater than zero using an assertion.

// Invariant
int getBalance() const { assert(balance >= 0); return balance; }
// Retrieve the balance value as an integer by calling the getBalance function, ensuring that it
doesn't violate the assertion that balance must be greater than or equal to zero.

56
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Composition over inheritance.

❑ Composition over inheritance is a fundamental principle in object-oriented programming that encourages


` composition (building complex objects by combining simpler ones) instead of relying solely on class
favoring
inheritance. This approach offers more flexibility and reusability by allowing you to create new classes by
composing existing ones, reducing dependencies and potential issues associated with deep class hierarchies. It
promotes a modular and maintainable code structure. here are the key conditions for prioritizing composition
over inheritance:
➢ Flexibility and Reusability
➢ Avoiding Deep Class Hierarchies
➢ Reducing Tight Coupling
➢ Mixing Behaviors
➢ Testing and Debugging
➢ Runtime Behavior Modification
➢ Avoiding Fragile Base Class Problem
➢ Component-Based Architecture
➢ Maintainability

57
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Smart pointers and RAII.

Smart pointers
` and RAII are essential in OOP for managing resources and memory.
❑Smart pointers automatically handle memory, preventing leaks and access issues.
❑RAII ties resource lifetimes to objects, ensuring automatic management and
robust code.
❑They both align with OOP principles, improving code organization and safety.

58
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Managing object lifetimes.

❑ Managing object lifetimes in C++ is a critical aspect of writing efficient and bug-free code. It involves
`
controlling when objects are created and destroyed to ensure that resources are properly allocated
and deallocated.

❑ In C++, objects are created on the stack, in dynamic memory (heap), or as part of other objects.
Managing their lifetimes ensures that resources like memory, file handles, or network connections
are used efficiently and released when they are no longer needed. Properly managing object lifetimes
also helps prevent memory leaks and resource exhaustion.

59
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Managing object lifetimes.

Managing object lifetimes can be realized through several methods:


`
1- RAII (Resource Acquisition Is Initialization): RAII is a C++ programming idiom where resource management is tied
to object lifetimes. Resources are acquired in the constructor and released in the destructor, ensuring proper
cleanup.

class FileHandler {
public:
FileHandler(const std::string& filename) {} // Open the file
~FileHandler() {}
}; // Close the file

60
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Managing object lifetimes.

Managing object lifetimes can be realized through several methods:


`
2- Smart Pointers: C++ provides smart pointers like std::shared_ptr and std::unique_ptr to automate
memory management and ensure timely destruction of dynamic objects. They help prevent memory leaks.

std::shared_ptr<int> sharedValue = std::make_shared<int>(5001); // Shared


ownership

std::unique_ptr<int> uniqueValue = std::make_unique<int>(5001); // Exclusive


ownership

61
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Managing object lifetimes.

Managing object lifetimes can be realized through several methods:


`
3- Resource Management: Classes often manage resources like memory, files, or network connections.
Implementing constructors, destructors, and smart pointers helps ensure resources are properly
allocated and released.

class ResourceManager {public:

ResourceManager() {} // Resource allocation

~ResourceManager() {}
}; // Resource deallocation

62
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Managing object lifetimes.

Managing object lifetimes can be realized through several methods:


`
4- Dynamic Objects: Objects created in dynamic memory (heap) have a lifetime determined by the
programmer. You are responsible for allocating memory for them and releasing it when no longer
needed to prevent memory leaks.

int* dynamicValue = new int(10); // Allocating a dynamic object


delete dynamicValue; // Releasing the allocated memory

63
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Managing object lifetimes.

Managing object lifetimes can be realized through several methods:


`
5- Stack Objects: Objects created on the stack have a well-defined scope. They are automatically
destroyed when they go out of scope, such as when a function returns. Stack objects are suitable for
short-lived objects with a limited scope.

void exampleFunction() {
int x = 5; // 'x' is a stack object
} // 'x' is destroyed when the function ends

64
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Handling exceptions in class hierarchies.

Handling exceptions in class hierarchies involves managing exceptions thrown by base and derived
`
classes in a structured manner. In C++, when you have a hierarchy of classes, each derived class inherits
the base class's exception-handling behavior. We will have an example in which we will handle
exceptions in class hierarchies with theses given steps:

Step 1: Class Hierarchy: Define a hierarchy of classes representing different shapes.


Step 2: Class Definitions: Define the base class ‘Shape’ with a pure virtual draw() method. Create
derived classes ‘Circle’ and ‘Rectangle’, each with its own draw() method. The ‘Circle’ class intentionally
throws an exception.

65
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Handling exceptions in class hierarchies.

Step 4: main() Function: In the main() function, create an array of ‘Shape’ pointers containing instances of
`
both ‘Circle’ and ‘Rectangle’ objects. Iterate through the array and call the draw() method for each shape.

Step 5: Exception Handling: Use a try-catch block to catch exceptions that may be thrown during the drawing
operations. If an exception occurs (as in the case of the Circle), catch it and handle it by printing an error
message.

66
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Handling exceptions in class hierarchies.
#include <iostream>#include <stdexcept>
class Shape
` { public:virtual void draw() = 0; }; // Step 1: Class Hierarchy
class Circle : public Shape { public:void draw() override { throw
std::runtime_error("Circle drawing failed"); } };
// Step 2: Class definition (drawing code for a circle)
class Rectangle : public Shape { public: void draw() override {} }; // Drawing code
for a rectangle
int main() {
Shape* shapes[] = { new Circle(), new Rectangle() }; // Step 3: Main Function

for (Shape* shape : shapes) {


try { shape->draw(); } // Step 4: Exception Handling
catch (const std::exception& e) { std::cerr << "Exception caught: " << e.what() <<
std::endl; }}
return 0;} // Catch and handle exceptions

67
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Handling exceptions in class hierarchies.

class Circle : public Shape { public:void draw() override { throw


` a Circle class that inherits publicly from the Shape class. In the
// Declare
Circle class, override the draw method to throw an exception

std::runtime_error("Circle drawing failed"); } };


// In the overridden draw method of the Circle class, throw a std::runtime_error
exception with the message 'Circle drawing failed’

Shape* shapes[] = { new Circle(), new Rectangle() };


// Create an array of Shape pointers named shapes, containing instances of
Circle and Rectangle classes

68
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Handling exceptions in class hierarchies.

for (Shape*
` shape : shapes) {
try { shape->draw(); } // Step 4: Exception Handling
catch (const std::exception& e) { std::cerr << "Exception caught: " << e.what()
<< std::endl; }}

// In a loop that iterates through each Shape object in the shapes array, try to
execute the draw method. If an exception is thrown during the execution, catch
it as a std::exception reference, and print an error message containing the
exception's description

69
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Custom exception classes..

When developing complex software systems, it's often necessary to handle different types of errors or
exceptional
` situations gracefully. C++ provides a built-in exception mechanism that allows you to throw
and catch exceptions, which can be used to handle errors and abnormal conditions. Custom exception
classes extend this mechanism by allowing you to create exception types tailored to your application's
specific needs.
Here are the steps to throw an exception in C++, along with the required commands and their usage
format:
1- Include the Necessary Header: Begin by including the <stdexcept> header, which provides standard
exception classes and mechanisms.
#include <stdexcept> 70
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Custom exception classes..

2- Define a Custom Exception Class (Optional): If you want to create a custom exception class, derive it
from std::exception
` and override the what() method to provide a custom error message. This step is
optional but useful for creating meaningful exceptions.

class MyCustomException : public std::exception {


public: const char* what() const noexcept override { return "Custom
error message"; }
};

71
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Custom exception classes..

3- Throw an Exception: To raise an exception in your code, use the throw keyword followed by an
instance ` of an exception class. You can throw built-in exception classes like std::runtime_error,
std::logic_error, or custom exception classes.

throw std::runtime_error("An error occurred!");

//Or

throw MyCustomException();

72
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Custom exception classes..

4- Catch and Handle the Exception: In the calling code, use a try block to enclose the code that may
throw an`exception. Then, use one or more catch blocks to catch and handle the exception.

try {}
catch (const std::exception& e) { std::cerr << "Error: " << e.what() <<
std::endl; }

In C++, e.what() is a member function typically used with exception objects. When an exception is
thrown, it can carry an associated message or description.

73
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Custom exception classes..

5- Handle Different Types of Exceptions (Optional): If your code can throw multiple types of exceptions,
you can have
` multiple catch blocks to handle them differently based on their types.

try {}
catch (const MyCustomException& customException)
{
std::cerr << "Custom Exception: " << customException.what() << std::endl;
}
catch (const std::exception& stdException)
{
std::cerr << "Standard Exception: " << stdException.what() << std::endl;
}

74
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Custom exception classes..

catch (...)
{
std::cerr
` << "Unknown Exception!" << std::endl;
}

6- Handle Exceptions Gracefully: Within the catch blocks, you can implement error-handling logic, log
messages, clean up resources, or take appropriate actions based on the exception type.
7- Continue or Terminate the Program: After handling the exception, you can choose to continue
executing the program or terminate it gracefully, depending on your application's requirements.

75
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Overview of the OOAD process.

❑ Object-Oriented Analysis and Design (OOAD) is a systematic approach to designing software systems
`
using object-oriented principles. It involves defining the structure and behavior of a software system
by modeling it using various techniques, including UML diagrams, to understand, plan, and
communicate the system's architecture.
The OOAD process typically consists of several key stages:
➢ Requirements Gathering
➢ System Modeling
➢ Implementation
➢ Deployment

76
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ Overview of the OOAD process.

➢ Requirements Gathering: This stage involves collecting and analyzing user requirements to understand what the
` to do. It focuses on defining the problem domain and identifying the main functionalities and
system needs
constraints.
➢ System Modeling: During this phase, developers create models to represent the system's structure and behavior.
Common modeling techniques include creating UML class diagrams, use case diagrams, and sequence diagrams.
➢ Design: In the design phase, developers use the models created in the previous step to design the architecture of the
system. This includes defining classes, their attributes, methods, and the relationships between them.
➢ Implementation: This is where developers write the actual code for the system based on the design. In C++, this
involves creating classes, defining member functions, and implementing the behavior described in the design phase.
➢ Testing: Testing ensures that the software meets the specified requirements. It involves various levels of testing, from
unit testing of individual classes to integration testing and system testing.
➢ Deployment: Once the software is thoroughly tested and validated, it is deployed to the target environment for end-
users to use.

77
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ UML diagrams for modeling.
UML (Unified Modeling Language) diagrams provide a standardized way to visualize the components
`
and relationships of a software system. In C++, UML class diagrams are commonly used to represent
classes, their attributes, methods, and associations between classes. These diagrams help in
understanding the structure of a C++ program, facilitating communication among developers, and aiding
in code design and organization.
➢ Let’s see a code represents three classes: Library, Book, and Member, along with their respective
attributes and methods. Each class is represented inside a box, and the attributes and methods are
listed beneath each class. While this code is not executable C++ code, it serves as a visual
representation of the structure and relationships between classes in a software system. It can be
used as a blueprint for implementing the actual C++ classes and their functionality.

78
CSI2372 - Advanced Programming Concepts with C++
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
➢ UML diagrams for modeling.

` +------------------------+
+------------------------+ +------------------------+
| Library | | Book | | Member |
+------------------------+ +------------------------+ +------------------------+
| - name: string | | - title: string | | - name: string |
| - books: vector<Book> | | - author: string | | - memberId: int |
+------------------------+ | - ISBN: string | +------------------------+
| + addBook(book: Book) | +------------------------+ | + borrowBook(book: Book) |
| + removeBook(book: Book) | | + returnBook(book: Book) |
| + listBooks() | +------------------------+
+------------------------+

79
Thank you

80

You might also like