C++.Module 03
C++.Module 03
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
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;
// 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.
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;
}
};
Call Time Called when an object is created Called when an object is destroyed
Return
No return type (not even void) No return type
Type
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).
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
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;
}
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;
}
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.
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;
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.
int main() {
vector<int> arr = {5, 2, 9, 1, 5, 6};
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<>
int main() {
vector<int> arr = {5, 2, 9, 1, 5, 6};
Output: 9 6 5 5 2 1
• The function greater<int>() is passed as the third argument to sort the vector in descending order.
int main() {
vector<int> arr = {-5, -3, 7, 2, -8, 4};
Output: 2 -3 4 -5 7 -8
• The custom comparator customCompare sorts the elements based on their absolute values.