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

C++.Module 03

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

C++.Module 03

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

 C++ is based on classes and objects

 A class is a user-defined data type that serves as a blueprint for creating objects.
 An object is an instance of a class with specific attribute values and access to its methods.
 Objects have attributes (e.g., weight, color) and methods (e.g., drive, brake)
 Attributes are variables; methods are functions within the class
 Class members refer to both attributes and methods

Class Objects Class Members (Objects Have)


Bike Suzuki Attributes:
TVS Model
Yamaha Color
Honda Engine capacity
Hero Weight
Bajaj Fuel type
Harley Davidson Mileage
Price

Methods:
startEngine()
stopEngine()
accelerate()
brake()
refuel()
changeGear()
checkMileage()

Class Definition
class Bike {
public:
// Attributes (variables)
string model;
string color;
int engineCapacity;

// Methods (functions)
void startEngine() {
cout << "Engine started" << endl;
}
void stopEngine() {
cout << "Engine stopped" << endl;
}
};
Creating Objects
int main() {
// Creating objects of Bike class
Bike suzuki;
Bike yamaha;

// Assigning values to attributes


suzuki.model = "Suzuki Gixxer";
suzuki.color = "Black";
suzuki.engineCapacity = 150;

yamaha.model = "Yamaha R15";


yamaha.color = "Blue";
yamaha.engineCapacity = 155;

// Calling methods
suzuki.startEngine();
yamaha.stopEngine();

return 0;
}

Example:
#include <bits/stdc++.h>
cout << aiyan.name << endl;
using namespace std; cout << aiyan.cls << endl;
cout << aiyan.roll << endl;
class Student cout << aiyan.section << endl << endl;
{
public: Student rihan;
char name[50]; strcpy(rihan.name, "Rihan");
int roll; rihan.cls = 5;
int cls; rihan.roll = 01;
char section; rihan.section = 'A';
};
cout << rihan.name << endl;
int main() cout << rihan.cls << endl;
{ cout << rihan.roll << endl;
Student aiyan; cout << rihan.section << endl;
strcpy(aiyan.name, "Aiyan");
aiyan.cls = 10; return 0;
aiyan.roll = 01; }
aiyan.section = 'A';
A constructor is a special method in object-oriented programming (OOP) that is automatically called
when an object is created. It is primarily used to initialize the object's properties or execute any startup
procedures.

• Purpose: Initialize the object’s state (e.g., assigning values to attributes).


• Name: Same as the class name.
• Called When: Automatically invoked at the time of object creation.
• No Return Type: Constructors do not return values (not even void).
• Types:
o Default Constructor: Takes no parameters and provides default values.
o Parameterized Constructor: Takes arguments to initialize the object with specific
values.

Example in C++:
class Car {
public:
string brand;
int year;

// Constructor
Car(string b, int y) {
brand = b;
year = y;
}
};

A destructor is also a special method in OOP, and it is called automatically when an object is
destroyed. Its main job is to clean up resources (like memory, file handles, etc.) used by the object
before it is removed from memory.

• Purpose: Free up resources or execute cleanup operations before the object is destroyed.
• Name: Same as the class name, but preceded by a tilde (~).
• Called When: Automatically invoked when an object goes out of scope or is explicitly deleted.
• No Parameters and No Return Type: Destructors do not take parameters or return any
values.
• Single Destructor: A class can only have one destructor.
Example in C++:
class Car {
public:
string brand;
int year;

// Constructor
Car(string b, int y) {
brand = b;
year = y;
}

// Destructor
~Car() {
// Cleanup code (if any)
cout << "Object destroyed!" << endl;
}
};

Key Differences Between Constructor and Destructor:


Feature Constructor Destructor

Clean up before the object is


Purpose Initialize object properties
destroyed

Call Time Called when an object is created Called when an object is destroyed

Same as class name, with a ~


Name Same as class name
prefix

Return
No return type (not even void) No return type
Type

Can have parameters (for parameterized


Parameters Cannot have parameters
constructors)
There are three ways to return an object from a function. They are:
i. Return by value
i. Return by reference
ii. Return by pointer

Return by value
• A copy of the object is returned.
• Can cause overhead due to copying.
• Modern C++ optimizations (RVO) often prevent unnecessary copying.

Car createCar() {
Car myCar("Tesla", 2023);
return myCar; // Returns a copy of the object
}

Example:
class Car {
public:
string brand;
int year;

// Constructor
Car(string b, int y) {
brand = b;
year = y;
}

void display() {
cout << "Brand: " << brand << ", Year: " << year << endl;
}
};
// Function that returns an object by value
Car createCar() {
Car myCar("Tesla", 2023);
return myCar; // Returns a copy of the myCar object
}
int main() {
Car car1 = createCar(); // car1 is a copy of the object returned by
createCar
car1.display();
return 0;
}
Return by reference
• The function returns a reference to the object.
• More efficient (no copying), but be cautious of dangling references.
• Do not return references to local variables (they go out of scope).

Car& modifyCar(Car& car) {


car.year = 2024;
return car; // Returns a reference to the original object
}

Example:
Car& modifyCar(Car& car) {
car.year = 2024;
return car; // Returns a reference to the original car object
}
int main() {
Car myCar("BMW", 2021);
Car& updatedCar = modifyCar(myCar); // myCar is modified
updatedCar.display(); // Displays: Brand: BMW, Year: 2024
return 0;
}

Return by pointer
• The function returns a pointer to the object, useful when the object is dynamically allocated.
• Requires manual memory management (delete to free memory).
Car* createDynamicCar() {
Car* newCar = new Car("Audi", 2022); // Dynamic memory allocation
return newCar; // Returns pointer to the object
}

Example:
Car* createDynamicCar() {
Car* newCar = new Car("Audi", 2022); // Dynamically allocated object
return newCar; // Returns a pointer to the dynamically allocated Car
}
int main() {
Car* carPtr = createDynamicCar(); // carPtr points to the object returned by
createDynamicCar
carPtr->display(); // Use -> to access the members
delete carPtr; // Don't forget to free the dynamically allocated memory
return 0;
}
Comparison of Return Methods:
Return Memory
Safety Use Case
Method Efficiency

Less efficient Safe (no dangling references or When object size is small or
By Value
(copying) memory leaks) copy elision applies

By Efficient (no Risk of dangling references if not When object needs to be


Reference copy) handled properly modified or shared

Efficient (no Requires manual memory When using dynamic


By Pointer
copy) management, risk of memory leaks memory (heap allocation)
Stack Memory Allocation:
• Automatic memory allocation.
• Objects are automatically destroyed when they go out of scope.
• Fast and managed by the system, but limited in size.

Example of Stack Allocation:


class Car {
public:
string brand;
int year;

Car(string b, int y) {
brand = b;
year = y;
}

void display() {
cout << "Brand: " << brand << ", Year: " << year << endl;
}
};

int main() {
Car myCar("Ford", 2023); // Stack allocation
myCar.display(); // Car object is automatically destroyed at the end of
scope
return 0;
}

• Memory: Allocated on the stack.


• Deallocation: Happens automatically when the function (main here) exits.
• Speed: Faster but memory is limited.

2. Heap Memory Allocation:


• Dynamic memory allocation (using new keyword).
• Memory must be manually freed using delete to avoid memory leaks.
• Suitable for long-lived objects and large memory requirements.

Example of Heap Allocation:


class Car {
public:
string brand;
int year;

Car(string b, int y) {
brand = b;
year = y;
}

void display() {
cout << "Brand: " << brand << ", Year: " << year << endl;
}
};

int main() {
Car* myCar = new Car("Tesla", 2023); // Heap allocation
myCar->display(); // Use -> for accessing members
delete myCar; // Manually deallocate memory to prevent memory leak
return 0;
}

• Memory: Allocated on the heap using new.


• Deallocation: Must use delete to free up memory.
• Flexibility: Can allocate memory dynamically during runtime, making it suitable for larger or more
persistent objects.

Stack vs. Heap Comparison:


Feature Stack Heap

Memory Dynamic, controlled by the


Automatic and scoped
Allocation programmer

Speed Fast Slower (due to dynamic allocation)

Size Limited Larger than stack

Objects destroyed automatically when out of


Lifetime Programmer must manage manually
scope

Usage Small objects, short-lived variables Large objects, long-lived objects


Hybrid Example: Simulating Stack and Heap Memory Together
#include <iostream>
using namespace std;

class Car {
public:
string brand;
int year;

Car(string b, int y) {
brand = b;
year = y;
}

void display() {
cout << "Brand: " << brand << ", Year: " << year << endl;
}
};

int main() {
// Stack allocation
Car stackCar("Toyota", 2022);
stackCar.display(); // Automatically destroyed at the end of the scope

// Heap allocation
Car* heapCar = new Car("BMW", 2023);
heapCar->display();
delete heapCar; // Must delete to prevent memory leak

return 0;
}

Key Points:
• Stack memory is suitable for small, short-lived objects that are automatically managed.
• Heap memory is better for dynamic, large, or long-lived objects but requires manual management.
• Mixing stack and heap allocations gives flexibility in how memory is managed in a program.

Dynamic Object যখন ইচ্ছা মেমোরি মেমে রিরিট েিা যায়। রেন্তু সচিাচি Created Object
মরাগ্রাে মেষ না হওয়া পযযন্ত মেমোরি মেমে রিরিট েিা যায় না।
Dynamic Object িাইনারেে অ্যামিি েম া Heap মেমোরিম রিময়ইট হয়।
Object name জায়গা দখি েমি না রেন্তু Variables মেমোরিম জায়গা দখি েমি।
Steps to Access Values in a Dynamic Object:
1. Create the Object Dynamically: Use the new keyword to allocate memory for the object.
2. Access Members via Pointer: Use the arrow operator (->) to access the object’s members.
3. Deallocate the Object: Use the delete keyword to free up the memory to avoid memory leaks.

Example: Accessing Values of a Dynamic Object


#include <iostream>
using namespace std;

class Car {
public:
string brand;
int year;

Car(string b, int y) {
brand = b;
year = y;
}

void display() {
cout << "Brand: " << brand << ", Year: " << year << endl;
}
};

int main() {
// Create a dynamic object using 'new'
Car* myCar = new Car("Tesla", 2023); // 'myCar' is a pointer to a Car object

// Accessing members using the pointer and the arrow (->) operator
cout << "Accessing brand directly: " << myCar->brand << endl;
cout << "Accessing year directly: " << myCar->year << endl;

// Using a method of the dynamic object


myCar->display(); // Equivalent to (*myCar).display()

// Deallocate the dynamic object using 'delete'


delete myCar; // Free the memory
return 0;
}
Arrow Operator (->) vs. Dereferencing Operator (*)

• Arrow Operator (->):


o Used to access members of an object through a pointer.
o Syntax: pointer->member
• Dereferencing Operator (*):
o You can dereference the pointer and then access the member using the dot (.) operator.
o Syntax: (*pointer).member

Example:
cout << myCar->brand; // Using the arrow operator
cout << (*myCar).brand; // Equivalent using dereferencing

Summary:
• Use the arrow operator (->) to access values and methods of a dynamically allocated object
(heap memory).
• Always remember to deallocate dynamically allocated memory using delete to prevent memory
leaks.
The sort function is a standard library function in C++ used to sort elements in a range. It is part of
the <algorithm> header and can sort any array or container that supports random access, such as
vectors or arrays.

Syntax:
sort(startIterator, endIterator);

Parameters:
• startIterator: Iterator pointing to the first element of the range to be sorted.
• endIterator: Iterator pointing to the element just past the last element of the range to be
sorted (not included in the range).

By default, sort uses ascending order to sort the elements. However, you can provide a custom
comparison function to define your own sorting criteria.

Basic Example (Sorting in Ascending Order):


#include <iostream>
#include <algorithm> // Required for sort()
#include <vector>

using namespace std;

int main() {
vector<int> arr = {5, 2, 9, 1, 5, 6};

// Sort in ascending order


sort(arr.begin(), arr.end());

// Print sorted array


for (int i : arr) {
cout << i << " ";
}
return 0;
}

Output: 1 2 5 5 6 9

• The function sort(arr.begin(), arr.end()) sorts the vector arr in ascending order.
Sorting in Descending Order:
To sort in descending order, you can use the greater<int>() comparator from the <functional>
header.

#include <iostream>
#include <algorithm>
#include <vector>
#include <functional> // Required for greater<>

using namespace std;

int main() {
vector<int> arr = {5, 2, 9, 1, 5, 6};

// Sort in descending order


sort(arr.begin(), arr.end(), greater<int>());

// Print sorted array


for (int i : arr) {
cout << i << " ";
}
return 0;
}

Output: 9 6 5 5 2 1

• The function greater<int>() is passed as the third argument to sort the vector in descending order.

Sorting with a Custom Comparator:


You can define your own custom comparison function or lambda to sort elements based on any
criteria.

Example: Sorting based on the absolute values of integers.


#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath> // Required for abs()

using namespace std;

// Custom comparator to sort by absolute values


bool customCompare(int a, int b) {
return abs(a) < abs(b);
}

int main() {
vector<int> arr = {-5, -3, 7, 2, -8, 4};

// Sort based on absolute values


sort(arr.begin(), arr.end(), customCompare);

// Print sorted array


for (int i : arr) {
cout << i << " ";
}
return 0;
}

Output: 2 -3 4 -5 7 -8

• The custom comparator customCompare sorts the elements based on their absolute values.

Summary of Key Points:


1. Header File: #include <algorithm>
2. Default Sorting: sort() sorts in ascending order by default.
3. Custom Sorting: Use a custom comparison function or lambda expression for custom sorting
behavior.
4. Efficiency: sort() uses a highly efficient algorithm (typically introsort), with a time complexity
of O(N log N).

You might also like