Opp Summerised
Opp Summerised
1. Overview
• What is C++?
o C++ is a high-performance programming language used for developing
software, games, and system applications.
o It supports object-oriented programming (OOP), which organizes code into
reusable objects.
• Key Features:
o Object-Oriented Programming (OOP): Encapsulation, inheritance, and
polymorphism.
o Standard Template Library (STL): Provides pre-built data structures and
algorithms.
o Portability: C++ code can run on multiple platforms (Windows, Mac, Linux).
• Why Learn C++?
o It offers fine-grained control over system resources and memory.
o It is widely used in industries like gaming, finance, and robotics.
o It is fast and efficient, making it ideal for performance-critical applications.
Advantages of C++
1. High Performance:
o Compiled language with direct machine code execution.
o Allows low-level memory manipulation for fine-grained control.
2. Object-Oriented Programming (OOP):
o Supports encapsulation, inheritance, and polymorphism.
o Promotes code reusability and modularity.
3. Rich Standard Library (STL):
o Provides pre-built data structures and algorithms.
o Reduces the need to write code from scratch.
4. Portability:
o Code can run on multiple platforms (Windows, Linux, macOS) with minimal
changes.
5. Memory Management:
o Manual memory management gives developers control over system resources.
Disadvantages of C++
1. Complexity:
o Steep learning curve due to advanced features like pointers and OOP.
o Can be overcomplicated for small projects.
2. Manual Memory Management:
o No garbage collection, leading to potential memory leaks or dangling pointers.
3. Verbose Syntax:
o Requires more code compared to modern languages like Python.
4. Security Vulnerabilities:
o Prone to issues like buffer overflows and pointer misuse.
5. Slow Development Cycle:
o Compilation process can be time-consuming for large projects.
o Not ideal for rapid prototyping.
2. Environment Setup
• Tools Needed:
o Text Editor: VS Code, Notepad++, or Sublime Text.
o Compiler: GCC, Clang, or Visual Studio.
• Online Compiler:
o Use www.compileonline.com to run C++ code without installation.
• Local Setup:
o Windows: Install MinGW or Visual Studio.
o Linux: Use sudo apt-get install g++ to install GCC.
o Mac: Install Xcode from the App Store.
3. Basic Syntax
• Structure of a C++ Program:
#include <iostream> // Include input/output library
using namespace std; // Use the standard namespace
• Explanation:
o #include <iostream>: Allows input/output operations.
o using namespace std;: Lets you use cout and cin without writing std::.
o int main(): The starting point of the program.
o cout << "Hello World!";: Prints text to the console.
o return 0;: Ends the program successfully.
4. Comments in C++
• Single-line Comments:
// This is a single-line comment
• Multi-line Comments:
/* This is a
multi-line comment */
5. Data Types
• Primitive Data Types:
Data Type Description Example
int Integer numbers int age = 25;
float Floating-point numbers float pi = 3.14;
double Double-precision floating-point double salary = 5000.50;
char Single character char grade = 'A';
bool Boolean (true/false) bool isTrue = true;
6. Variable Types
• Variables: Used to store data that can change.
int x = 10; // Declare and initialize a variable
x = 20; // Change the value of x
7. Variable Scope
• Local Variables: Declared inside a function and accessible only within that function.
void myFunction() {
int x = 10; // Local variable
cout << x;
}
• Global Variables: Declared outside all functions and accessible throughout the program.
int x = 10; // Global variable
void myFunction() {
cout << x;
}
8. Constants/Literals
• Integer Literals: Whole numbers (e.g., 10, -5).
• Floating-point Literals: Decimal numbers (e.g., 3.14, -0.5).
• Boolean Literals: true or false.
• Character Literals: Single characters enclosed in single quotes (e.g., 'A', '1').
• String Literals: Sequence of characters enclosed in double quotes (e.g., "Hello").
9. Modifier Types
• Type Modifiers: Change the meaning of the base data type.
o signed: Can store positive and negative values.
o unsigned: Can store only positive values.
o short: Reduces the size of the data type.
o long: Increases the size of the data type.
11. Operators
• Arithmetic Operators: +, -, *, /, %
• Relational Operators: ==, !=, >, <, >=, <=
• Logical Operators: &&, ||, !
• Bitwise Operators: &, |, ^, ~, <<, >>
• Assignment Operators: =, +=, -=, *=, /=
12. Loop Types
Loops are used to repeat a block of code multiple times until a specific condition is met. C++
provides three types of loops:
• For Loop:
Used when the number of iterations is known in advance.
Combines initialization, condition, and update in a single line
Key Points:
Initialization: Executed once at the start.
Condition: Checked before each iteration. If false, the loop ends.
Update: Executed after each iteration.
for (int i = 0; i < 5; i++) {
cout << i << endl;
}
• While Loop:
Used when the number of iterations is not known in advance.
Continues executing as long as the condition is true.
Key Points:
The condition is checked before each iteration.
If the condition is false initially, the loop never executes.
int i = 0;
while (i < 5) {
cout << i << endl;
i++;
}
• Do-While Loop:
Similar to the while loop, but the condition is checked after the loop body.
Ensures the loop executes at least once.
Key Points:
The loop body executes at least once, even if the condition is false.
Useful for scenarios where the loop must run before checking the condition.
int i = 0;
do {
cout << i << endl;
i++;
} while (i < 5);
• if-else Statement
Executes one block of code if the condition is true and another if it is false.
int age = 15;
if (age >= 18) {
cout << "You are an adult.";
} else {
cout << "You are a minor."; // Output: You are a minor.
}
• Switch Statement:
Used to select one of many code blocks to execute based on the value of a variable.
int day = 3;
switch (day) {
case 1: cout << "Monday"; break;
case 2: cout << "Tuesday"; break;
default: cout << "Invalid day";
}
14. Functions
Functions in C++
Functions are blocks of code that perform a specific task. They help in organizing code,
reducing redundancy, and improving readability. Functions can take inputs (parameters),
process them, and return a result.
1. Function Definition
• Return type: The type of value the function returns (e.g., int, void).
• Function name: The name of the function (e.g., add, printMessage).
• Parameters: Inputs to the function (optional).
• Function body: The code that performs the task.
Syntax:
return_type function_name(parameter_list) {
// Function body
return value; // Optional (only if return_type is not void)
}
Example:
int add(int a, int b) {
return a + b;
}
A function declaration tells the compiler about the function's name, return type, and
parameters. It is used when the function is defined after it is called.
Syntax:
return_type function_name(parameter_list);
Example:
int add(int a, int b); // Function declaration
3. Function Call
A function is executed by calling it with the required arguments.
Syntax:
function_name(arguments);
Example:
int result = add(5, 10); // Function call
cout << result; // Output: 15
4. Types of Functions
a) Functions with No Return Type (void)
int main() {
printMessage(); // Output: Hello, World!
return 0;
}
b) Functions with Return Type
Example:
int multiply(int a, int b) {
return a * b;
}
int main() {
int result = multiply(3, 4);
cout << result; // Output: 12
return 0;
}
c) Functions with No Parameters
Example:
int getRandomNumber() {
return rand();
}
int main() {
cout << getRandomNumber();
return 0;
}
d) Functions with Default Arguments
• Default values can be assigned to parameters. If the caller does not provide a value, the
default is used.
Example:
int add(int a, int b = 10) {
return a + b;
}
int main() {
cout << add(5); // Output: 15 (uses default b = 10)
cout << add(5, 3); // Output: 8 (overrides default b)
return 0;
}
5. Function Overloading
• Multiple functions can have the same name but different parameters (number or type).
Example:
int add(int a, int b) {
return a + b;
}
int main() {
cout << add(5, 10) << endl; // Output: 15 (int version)
cout << add(3.5, 2.5) << endl; // Output: 6.0 (double version)
return 0;
}
6. Recursive Functions
• A function that calls itself is called a recursive function.
Example:
int factorial(int n) {
if (n == 0) return 1; // Base case
return n * factorial(n - 1); // Recursive call
}
int main() {
cout << factorial(5); // Output: 120
return 0;
}
7. Inline Functions
• Inline functions are expanded in place (like macros) to reduce the overhead of function
calls.
Syntax:
inline return_type function_name(parameters) {
// Function body
}
Example:
inline int square(int x) {
return x * x;
}
int main() {
cout << square(5); // Output: 25
return 0;
}
Example:
void increment(int x) {
x++;
}
int main() {
int a = 5;
increment(a);
cout << a; // Output: 5 (unchanged)
return 0;
}
b) Pass by Reference
Example:
void increment(int &x) {
x++;
}
int main() {
int a = 5;
increment(a);
cout << a; // Output: 6 (changed)
return 0;
}
Syntax:
[capture](parameters) -> return_type {
// Function body
}
Example:
auto add = [](int a, int b) -> int {
return a + b;
};
int main() {
cout << add(5, 10); // Output: 15
return 0;
}
int main() {
double radius;
cout << "Enter radius: ";
cin >> radius;
cout << "Area: " << calculateArea(radius);
return 0;
}
int main() {
int result = add(5, 10);
cout << "Sum: " << result;
return 0;
}
15. Numbers
Numbers in C++
In C++, numbers are represented using numeric data types like int, float, double, etc. C++
provides a wide range of mathematical operations and functions to work with numbers.
+ Addition 5+3 →8
- Subtraction 5-3 →2
* Multiplication 5*3 → 15
/ Division 5/2 →2
3. Mathematical Functions
C++ provides a <cmath> library for advanced mathematical operations.
Example:
#include <cmath>
#include <iostream>
using namespace std;
int main() {
cout << sqrt(25) << endl; // Output: 5
cout << pow(2, 3) << endl; // Output: 8
cout << abs(-10) << endl; // Output: 10
cout << ceil(3.2) << endl; // Output: 4
cout << floor(3.8) << endl; // Output: 3
cout << round(3.5) << endl; // Output: 4
return 0;
}
4. Random Numbers
Random numbers can be generated using the <cstdlib> and <ctime> libraries.
Example:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
int main() {
srand(time(0)); // Seed the random number generator
int randomNum = rand() % 100; // Random number between 0 and 99
cout << "Random number: " << randomNum;
return 0;
}
5. Number Formatting
C++ provides tools to format numbers, such as setting precision for floating-point numbers.
Example:
#include <iomanip>
#include <iostream>
using namespace std;
int main() {
double pi = 3.141592653589793;
cout << fixed << setprecision(2); // Set precision to 2 decimal places
cout << "Pi: " << pi << endl; // Output: Pi: 3.14
return 0;
}
6. Type Conversion
Example:
int a = 10;
double b = 3.5;
// Implicit conversion
double result1 = a + b; // int + double → double
cout << result1 << endl; // Output: 13.5
For very large numbers, use the long long data type.
Example:
long long bigNum = 1234567890123456789LL;
cout << bigNum << endl; // Output: 1234567890123456789
8. Common Pitfalls
1. Integer Division:
o Dividing two integers results in an integer (truncates the decimal part).
2. int a = 5, b = 2;
3. cout << a / b; // Output: 2 (not 2.5)
4. Overflow:
o Exceeding the range of a data type can cause unexpected behavior.
5. int a = 2147483647; // Maximum value for int
6. cout << a + 1; // Output: -2147483648 (overflow)
7. Precision Loss:
o Floating-point numbers may lose precision due to their limited representation.
8. float f = 0.1f;
9. cout << f; // Output: 0.1 (but may not be exact)
int main() {
double principal = 1000, rate = 0.05, time = 5;
double amount = principal * pow(1 + rate, time);
cout << "Compound Interest: " << amount - principal;
return 0;
}
• Math Operations:
#include <cmath>
cout << sqrt(16); // Output: 4
• Random Numbers:
#include <cstdlib>
#include <ctime>
srand(time(0));
cout << rand(); // Output: Random number
16. Arrays
• Arrays: Store multiple values of the same type.
Arrays in C++
An array is a collection of elements of the same data type stored in contiguous memory
locations. Arrays are used to store multiple values in a single variable, making it easier to
manage and manipulate data.
1. Declaring an Array
Syntax:
data_type array_name[array_size];
Example:
int numbers[5]; // Declares an array of 5 integers
2. Initializing an Array
Example:
int numbers[5] = {10, 20, 30, 40, 50}; // Initializes an array with 5 values
Syntax:
array_name[index];
Example:
int numbers[5] = {10, 20, 30, 40, 50};
cout << numbers[0]; // Output: 10
cout << numbers[2]; // Output: 30
4. Modifying Array Elements
Example:
int numbers[5] = {10, 20, 30, 40, 50};
numbers[1] = 25; // Changes the second element to 25
cout << numbers[1]; // Output: 25
Example:
int numbers[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++) {
cout << numbers[i] << " "; // Output: 10 20 30 40 50
}
6. Multidimensional Arrays
Syntax:
data_type array_name[row_size][column_size];
Example:
int matrix[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
// Accessing elements
cout << matrix[0][1]; // Output: 2
Iterating Through a 2D Array:
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
Arrays can be passed to functions by reference (the array name is a pointer to its first element).
Example:
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
}
int main() {
int numbers[5] = {10, 20, 30, 40, 50};
printArray(numbers, 5); // Output: 10 20 30 40 50
return 0;
}
8. Array Limitations
For arrays with a size determined at runtime, use dynamic memory allocation.
Example:
int* arr = new int[5]; // Dynamically allocate an array of size 5
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
}
delete[] arr; // Free the allocated memory
The <array> header provides a safer and more flexible alternative to traditional arrays.
Example:
#include <array>
#include <iostream>
using namespace std;
int main() {
array<int, 5> numbers = {10, 20, 30, 40, 50};
for (int i = 0; i < numbers.size(); i++) {
cout << numbers[i] << " "; // Output: 10 20 30 40 50
}
return 0;
}
11. Common Array Operations
a) Finding the Largest Element
int numbers[5] = {10, 20, 30, 40, 50};
int max = numbers[0];
for (int i = 1; i < 5; i++) {
if (numbers[i] > max) {
max = numbers[i];
}
}
cout << "Max: " << max; // Output: Max: 50
b) Sum of Array Elements
int numbers[5] = {10, 20, 30, 40, 50};
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += numbers[i];
}
cout << "Sum: " << sum; // Output: Sum: 150
c) Reversing an Array
int numbers[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5 / 2; i++) {
swap(numbers[i], numbers[4 - i]);
}
for (int i = 0; i < 5; i++) {
cout << numbers[i] << " "; // Output: 50 40 30 20 10
}
Strings are used to store and manipulate sequences of characters. In C++, strings can be
handled in two ways:
1. C-Style Strings
Syntax:
char string_name[size];
Example:
char name[20] = "John"; // Declares a C-style string
• Direct Initialization:
• char name[] = "John"; // Automatically adds '\0' at the end
• Character-by-Character Initialization:
• char name[5] = {'J', 'o', 'h', 'n', '\0'};
Example:
char name[] = "John";
cout << name[0]; // Output: J
cout << name[2]; // Output: h
strstr(str, substr) Finds the first occurrence of substr in str strstr("Hello", "lo") → "lo"
Example:
#include <cstring>
#include <iostream>
using namespace std;
int main() {
char str1[20] = "Hello";
char str2[20] = "World";
The std::string class (from the <string> library) provides a more convenient and safer way to
handle strings.
Syntax:
#include <string>
using namespace std;
string string_name;
Example:
#include <string>
#include <iostream>
using namespace std;
int main() {
string name = "John";
cout << name; // Output: John
return 0;
}
6. Common std::string Operations
Operation Description Example
str.length() Returns the length of the string name.length() →4
str.replace(pos, len, str2) Replaces part of the string with str2 name.replace(1, 2, "ane") → "Jane"
Example:
#include <string>
#include <iostream>
using namespace std;
int main() {
string name = "John";
cout << name.length() << endl; // Output: 4
name.append(" Doe");
cout << name << endl; // Output: John Doe
cout << name.substr(5, 3) << endl; // Output: Doe
return 0;
}
int main() {
string str = "madam";
string reversed = str;
reverse(reversed.begin(), reversed.end());
if (str == reversed) {
cout << "Palindrome!";
} else {
cout << "Not a palindrome!";
}
return 0;
}
18. Pointers
Pointers in C++
Pointers are variables that store memory addresses of other variables. They are a powerful
feature of C++ that allows for dynamic memory management, efficient array handling, and
passing large structures to functions.
1. Pointer Declaration
Syntax:
data_type* pointer_name;
Example:
int* ptr; // Declares a pointer to an integer
Use the address-of operator (&) to get the memory address of a variable.
Example:
int num = 10;
int* ptr = # // ptr now holds the address of num
3. Accessing Values Using Pointers
Use the dereference operator (*) to access the value stored at the memory address a pointer
points to.
Example:
int num = 10;
int* ptr = #
cout << *ptr; // Output: 10 (value at the address stored in ptr)
4. Pointer Arithmetic
Pointers support arithmetic operations like addition, subtraction, increment, and decrement.
These operations are based on the size of the data type the pointer points to.
Example:
int arr[3] = {10, 20, 30};
int* ptr = arr; // Points to the first element of the array
Arrays and pointers are closely related. The name of an array is a pointer to its first element.
Example:
int arr[3] = {10, 20, 30};
int* ptr = arr; // ptr points to the first element of arr
6. Pointers to Pointers
Syntax:
data_type** pointer_name;
Example:
int num = 10;
int* ptr = #
int** ptr2 = &ptr; // ptr2 points to ptr
Pointers are used to manage dynamic memory (memory allocated at runtime) using new and
delete.
a) Allocating Memory
int* ptr = new int; // Allocates memory for one integer
*ptr = 10; // Assigns a value to the allocated memory
b) Deallocating Memory
delete ptr; // Frees the allocated memory
c) Allocating Arrays
int* arr = new int[5]; // Allocates memory for an array of 5 integers
arr[0] = 10; // Assigns a value to the first element
delete[] arr; // Frees the allocated array memory
Pointers can be passed to functions to modify the original variable or to avoid copying large
data structures.
Example:
void increment(int* ptr) {
(*ptr)++; // Increments the value at the address stored in ptr
}
int main() {
int num = 10;
increment(&num); // Passes the address of num
cout << num; // Output: 11
return 0;
}
A null pointer does not point to any memory location. It is used to indicate that the pointer is not
initialized or is invalid.
Example:
int* ptr = nullptr; // Modern C++ (preferred)
int* ptr2 = NULL; // Older C++ (avoid)
int* ptr3 = 0; // Avoid (confusing)
1. Dangling Pointers: Pointers that point to memory that has been freed.
2. int* ptr = new int;
3. delete ptr;
4. // ptr is now a dangling pointer
5. Memory Leaks: Forgetting to free dynamically allocated memory.
6. int* ptr = new int;
7. // Forgot to delete ptr
8. Uninitialized Pointers: Using a pointer before assigning it a valid address.
9. int* ptr;
10. *ptr = 10; // Undefined behavior
int main() {
int x = 10, y = 20;
swap(&x, &y);
cout << "x: " << x << ", y: " << y; // Output: x: 20, y: 10
return 0;
}
19. References
References in C++
References are aliases for existing variables. They provide an alternative way to access and
manipulate data without using pointers. References are safer and easier to use than pointers
because they cannot be null and cannot be reassigned to refer to a different variable.
1. Reference Declaration
Syntax:
data_type& reference_name = variable_name;
Example:
int num = 10;
int& ref = num; // ref is a reference to num
2. Using References
Example:
int num = 10;
int& ref = num;
Memory Address Does not have its own memory address Has its own memory address
References are commonly used to pass arguments to functions by reference, allowing the
function to modify the original variable.
Example:
void increment(int& ref) {
ref++; // Modifies the original variable
}
int main() {
int num = 10;
increment(num); // Passes num by reference
cout << num; // Output: 11
return 0;
}
Functions can return references, but care must be taken to avoid returning references to local
variables (which go out of scope after the function ends).
Example:
int& getLarger(int& a, int& b) {
return (a > b) ? a : b;
}
int main() {
int x = 10, y = 20;
getLarger(x, y) = 30; // Modifies the larger variable (y)
cout << y; // Output: 30
return 0;
}
6. const References
Example:
void print(const int& ref) {
cout << ref; // Can read but not modify ref
}
int main() {
int num = 10;
print(num); // Passes num by const reference
return 0;
}
7. References and Arrays
Example:
int arr[3] = {10, 20, 30};
int(&ref)[3] = arr; // ref is a reference to the array
8. Common Pitfalls
1. Uninitialized References:
o References must be initialized when declared.
2. int& ref; // Error: Reference must be initialized
3. Returning References to Local Variables:
o Returning a reference to a local variable results in undefined behavior.
4. int& badFunction() {
5. int num = 10;
6. return num; // Error: num goes out of scope
7. }
9. Best Practices
1. Use references to avoid copying large objects when passing them to functions.
2. Prefer const references when you don’t need to modify the original variable.
3. Avoid returning references to local variables.
4. Use references instead of pointers when possible for safer and cleaner code.
int main() {
int x = 10, y = 20;
swap(x, y); // Passes x and y by reference
cout << "x: " << x << ", y: " << y; // Output: x: 20, y: 10
return 0;
}
20. Date and Time
Date and Time in C++
The <ctime> library provides functions to work with date and time in C-style.
• time_t: Represents the number of seconds since the Unix epoch (January 1, 1970).
• tm: A structure that holds date and time components (year, month, day, etc.).
Example:
#include <ctime>
#include <iostream>
using namespace std;
int main() {
time_t now = time(0); // Get current time
cout << "Seconds since epoch: " << now << endl;
The strftime function allows you to format date and time into a custom string.
Example:
#include <ctime>
#include <iostream>
using namespace std;
int main() {
time_t now = time(0);
tm* localTime = localtime(&now);
char buffer[80];
strftime(buffer, 80, "Today is %A, %B %d, %Y. Time: %I:%M %p", localTime);
cout << buffer << endl; // Output: Today is Monday, October 30, 2023. Time: 03:45 PM
return 0;
}
The <chrono> library (introduced in C++11) provides a modern and type-safe way to work with
date and time.
a) std::chrono::system_clock
Example:
#include <chrono>
#include <iostream>
#include <ctime>
using namespace std;
using namespace std::chrono;
int main() {
// Get current time
auto now = system_clock::now();
// Convert to time_t
time_t now_time_t = system_clock::to_time_t(now);
Example:
#include <chrono>
#include <iostream>
using namespace std;
using namespace std::chrono;
int main() {
auto start = high_resolution_clock::now(); // Start time
// Calculate duration
auto duration = duration_cast<milliseconds>(end - start);
cout << "Time taken: " << duration.count() << " milliseconds" << endl;
return 0;
}
c) std::chrono::time_point
Example:
#include <chrono>
#include <iostream>
using namespace std;
using namespace std::chrono;
int main() {
// Get current time point
auto now = system_clock::now();
// Convert to time_t
time_t now_time_t = system_clock::to_time_t(now);
time_t later_time_t = system_clock::to_time_t(oneHourLater);
// Print results
cout << "Current time: " << ctime(&now_time_t);
cout << "One hour later: " << ctime(&later_time_t);
return 0;
}
4. Best Practices
int main() {
// Get current time
auto now = system_clock::now();
time_t now_time_t = system_clock::to_time_t(now);
Input and output (I/O) operations in C++ are performed using the Standard Input/Output
Library, which is part of the <iostream> header. The two most commonly used objects are:
The cout object is used to display output on the console. It is used with the insertion operator
(<<).
Syntax:
cout << "Text or variable";
Example:
#include <iostream>
using namespace std;
int main() {
cout << "Hello, World!" << endl; // Output: Hello, World!
int num = 10;
cout << "The number is: " << num << endl; // Output: The number is: 10
return 0;
}
The cin object is used to read input from the keyboard. It is used with the extraction operator
(>>).
Syntax:
cin >> variable;
Example:
#include <iostream>
using namespace std;
int main() {
int num;
cout << "Enter a number: ";
cin >> num; // Reads input from the user
cout << "You entered: " << num << endl;
return 0;
}
3. Handling Multiple Inputs
Example:
#include <iostream>
using namespace std;
int main() {
int a, b;
cout << "Enter two numbers: ";
cin >> a >> b; // Reads two numbers
cout << "Sum: " << a + b << endl;
return 0;
}
4. Reading Strings
a) Using cin
• cin reads input until the first whitespace character (space, tab, newline).
Example:
#include <iostream>
using namespace std;
int main() {
string name;
cout << "Enter your name: ";
cin >> name; // Reads a single word
cout << "Hello, " << name << "!" << endl;
return 0;
}
b) Using getline()
Example:
#include <iostream>
using namespace std;
int main() {
string fullName;
cout << "Enter your full name: ";
getline(cin, fullName); // Reads the entire line
cout << "Hello, " << fullName << "!" << endl;
return 0;
}
5. Formatting Output
You can format output using manipulators from the <iomanip> library.
Common Manipulators:
Manipulator Description Example
endl Inserts a newline and flushes the stream cout << "Hello" << endl;
setw(n) Sets the field width for the next output cout << setw(10) << "Hello";
setprecision(n) Sets the decimal precision for floating-point numbers cout << setprecision(2) << 3.14159;
fixed Displays floating-point numbers in fixed notation cout << fixed << 3.14159;
scientific Displays floating-point numbers in scientific notation cout << scientific << 3.14159;
Example:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double pi = 3.141592653589793;
cout << "Default: " << pi << endl;
cout << "Fixed (2 decimal places): " << fixed << setprecision(2) << pi << endl;
cout << "Scientific: " << scientific << pi << endl;
return 0;
}
You can check if the input operation was successful using the fail() method.
Example:
#include <iostream>
using namespace std;
int main() {
int num;
cout << "Enter a number: ";
cin >> num;
if (cin.fail()) {
cout << "Invalid input! Please enter a number." << endl;
cin.clear(); // Clears the error flag
cin.ignore(1000, '\n'); // Ignores the invalid input
} else {
cout << "You entered: " << num << endl;
}
return 0;
}
7. File Input/Output
C++ provides file streams (ifstream, ofstream) for reading from and writing to files.
a) Writing to a File
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream outFile("example.txt");
if (outFile.is_open()) {
outFile << "Hello, File!" << endl;
outFile.close();
} else {
cout << "Unable to open file!" << endl;
}
return 0;
}
b) Reading from a File
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream inFile("example.txt");
string line;
if (inFile.is_open()) {
while (getline(inFile, line)) {
cout << line << endl;
}
inFile.close();
} else {
cout << "Unable to open file!" << endl;
}
return 0;
}
8. Best Practices
int main() {
string name;
int age;
double salary;
return 0;
}
Data structures are used to organize and store data efficiently. C++ provides several built-in
data structures, as well as the ability to create custom ones. Below is an overview of the most
commonly used data structures in C++.
1. Arrays
2. Structures (struct)
struct Person {
string name;
int age;
};
3. Classes (class)
• Description: Similar to structures but with access control (public, private, protected) and
methods.
• Key Features:
o Encapsulates data and functions.
o Supports OOP concepts like inheritance and polymorphism.
• Example:
class Rectangle {
private:
int width, height;
public:
Rectangle(int w, int h) : width(w), height(h) {}
int area() { return width * height; }
};
#include <vector>
using namespace std;
#include <list>
using namespace std;
6. Stacks (std::stack)
• Description: A Last-In-First-Out (LIFO) data structure.
• Key Features:
o Elements are added and removed from the top.
o Provides methods like push(), pop(), and top().
• Example:
#include <stack>
using namespace std;
stack<int> s;
s.push(10);
s.push(20);
cout << s.top(); // Output: 20
s.pop();
cout << s.top(); // Output: 10
7. Queues (std::queue)
#include <queue>
using namespace std;
queue<int> q;
q.push(10);
q.push(20);
cout << q.front(); // Output: 10
q.pop();
cout << q.front(); // Output: 20
8. Maps (std::map)
#include <map>
using namespace std;
9. Sets (std::set)
#include <set>
using namespace std;
set<int> nums = {1, 2, 3};
nums.insert(4);
nums.insert(2); // Duplicate, ignored
for (int num : nums) {
cout << num << " "; // Output: 1 2 3 4
}
#include <unordered_map>
using namespace std;
class LinkedList {
private:
Node* head;
public:
LinkedList() : head(nullptr) {}
void append(int value) {
Node* newNode = new Node{value, nullptr};
if (!head) {
head = newNode;
} else {
Node* temp = head;
while (temp->next) {
temp = temp->next;
}
temp->next = newNode;
}
}
void print() {
Node* temp = head;
while (temp) {
cout << temp->data << " ";
temp = temp->next;
}
}
};
int main() {
LinkedList list;
list.append(10);
list.append(20);
list.append(30);
list.print(); // Output: 10 20 30
return 0;
}
1. Class Definition
A class defines the properties (attributes) and behaviors (methods) of objects.
Syntax:
class ClassName {
// Access specifiers: private, public, protected
private:
// Private members (not accessible outside the class)
public:
// Public members (accessible outside the class)
// Constructor(s)
// Methods
};
Example:
class Rectangle {
private:
int width, height;
public:
// Constructor
Rectangle(int w, int h) : width(w), height(h) {}
2. Object Creation
An object is an instance of a class. You can create objects using the class name.
Syntax:
ClassName objectName(arguments);
Example:
Rectangle rect(5, 10); // Creates an object of Rectangle
cout << "Area: " << rect.area(); // Output: Area: 50
3. Access Specifiers
Example:
class Person {
private:
string name;
int age;
public:
void setName(string n) {
name = n;
}
void setAge(int a) {
age = a;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Person p;
p.setName("John");
p.setAge(25);
p.display(); // Output: Name: John, Age: 25
return 0;
}
Example:
class Rectangle {
private:
int width, height;
public:
// Parameterized constructor
Rectangle(int w, int h) : width(w), height(h) {}
// Default constructor
Rectangle() : width(0), height(0) {}
int area() {
return width * height;
}
};
int main() {
Rectangle rect1(5, 10); // Calls parameterized constructor
Rectangle rect2; // Calls default constructor
cout << "Area: " << rect1.area() << endl; // Output: Area: 50
cout << "Area: " << rect2.area() << endl; // Output: Area: 0
return 0;
}
b) Destructors
Example:
class Rectangle {
private:
int width, height;
public:
Rectangle(int w, int h) : width(w), height(h) {}
~Rectangle() {
cout << "Rectangle destroyed!" << endl;
}
int area() {
return width * height;
}
};
int main() {
Rectangle rect(5, 10);
cout << "Area: " << rect.area() << endl; // Output: Area: 50
// Destructor is called automatically when rect goes out of scope
return 0;
}
5. Member Functions
Member functions are functions defined inside a class. They can access all members of the class.
Example:
class Circle {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() {
return 3.14159 * radius * radius;
}
double circumference() {
return 2 * 3.14159 * radius;
}
};
int main() {
Circle c(5);
cout << "Area: " << c.area() << endl; // Output: Area: 78.5397
cout << "Circumference: " << c.circumference() << endl; // Output: Circumference: 31.4159
return 0;
}
6. Static Members
Static members belong to the class rather than individual objects. They are shared by all objects
of the class.
Example:
class Counter {
private:
static int count; // Static member
public:
Counter() {
count++;
}
static int getCount() { // Static member function
return count;
}
};
int main() {
Counter c1, c2, c3;
cout << "Count: " << Counter::getCount() << endl; // Output: Count: 3
return 0;
}
Friend functions and classes can access private and protected members of a class.
a) Friend Function
class Rectangle {
private:
int width, height;
public:
Rectangle(int w, int h) : width(w), height(h) {}
friend void printArea(Rectangle r); // Friend function
};
void printArea(Rectangle r) {
cout << "Area: " << r.width * r.height << endl;
}
int main() {
Rectangle rect(5, 10);
printArea(rect); // Output: Area: 50
return 0;
}
b) Friend Class
class Rectangle {
private:
int width, height;
public:
Rectangle(int w, int h) : width(w), height(h) {}
friend class Printer; // Friend class
};
class Printer {
public:
void printArea(Rectangle r) {
cout << "Area: " << r.width * r.height << endl;
}
};
int main() {
Rectangle rect(5, 10);
Printer p;
p.printArea(rect); // Output: Area: 50
return 0;
}
8. Inheritance
Inheritance allows a class to inherit properties and behaviors from another class.
Example:
class Shape {
protected:
int width, height;
public:
Shape(int w, int h) : width(w), height(h) {}
};
int main() {
Rectangle rect(5, 10);
cout << "Area: " << rect.area() << endl; // Output: Area: 50
return 0;
}
9. Polymorphism
Polymorphism allows objects of different classes to be treated as objects of a common base class.
Example:
class Shape {
public:
virtual void draw() {
cout << "Drawing a shape" << endl;
}
};
int main() {
Shape* shape = new Circle();
shape->draw(); // Output: Drawing a circle
delete shape;
return 0;
}
24. Inheritance
Inheritance in C++
Inheritance is a fundamental concept in Object-Oriented Programming (OOP) that allows a
class (called the derived class) to inherit properties and behaviors (methods) from another class
(called the base class). This promotes code reuse and establishes a hierarchical relationship
between classes.
• Base Class (Parent Class): The class whose properties and methods are inherited.
• Derived Class (Child Class): The class that inherits from the base class.
Syntax:
class BaseClass {
// Base class members
};
• access_specifier: Can
be public, private, or protected. It determines the accessibility of the base
class members in the derived class.
2. Types of Inheritance
a) Single Inheritance
Example:
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
int main() {
Dog dog;
dog.eat(); // Output: Eating...
dog.bark(); // Output: Barking...
return 0;
}
b) Multiple Inheritance
Example:
class A {
public:
void displayA() {
cout << "Class A" << endl;
}
};
class B {
public:
void displayB() {
cout << "Class B" << endl;
}
};
c) Multilevel Inheritance
Example:
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
int main() {
Puppy puppy;
puppy.eat(); // Output: Eating...
puppy.bark(); // Output: Barking...
puppy.weep(); // Output: Weeping...
return 0;
}
d) Hierarchical Inheritance
Example:
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
int main() {
Dog dog;
dog.eat(); // Output: Eating...
dog.bark(); // Output: Barking...
Cat cat;
cat.eat(); // Output: Eating...
cat.meow(); // Output: Meowing...
return 0;
}
e) Hybrid Inheritance
Example:
class A {
public:
void displayA() {
cout << "Class A" << endl;
}
};
class B : public A {
public:
void displayB() {
cout << "Class B" << endl;
}
};
class C {
public:
void displayC() {
cout << "Class C" << endl;
}
};
class D : public B, public C {
public:
void displayD() {
cout << "Class D" << endl;
}
};
int main() {
D obj;
obj.displayA(); // Output: Class A
obj.displayB(); // Output: Class B
obj.displayC(); // Output: Class C
obj.displayD(); // Output: Class D
return 0;
}
• Constructors: Base class constructors are called before derived class constructors.
• Destructors: Derived class destructors are called before base class destructors.
Example:
class Base {
public:
Base() {
cout << "Base Constructor" << endl;
}
~Base() {
cout << "Base Destructor" << endl;
}
};
int main() {
Derived obj;
return 0;
}
Output:
Base Constructor
Derived Constructor
Derived Destructor
Base Destructor
5. Function Overriding
• A derived class can override a method of the base class to provide its own
implementation.
• Use the override keyword (C++11 and later) to explicitly indicate overriding.
Example:
class Animal {
public:
virtual void sound() {
cout << "Animal sound" << endl;
}
};
int main() {
Animal* animal = new Dog();
animal->sound(); // Output: Bark
delete animal;
return 0;
}
6. Best Practices
Overloading allows you to define multiple functions or operators with the same name but
different parameters or behaviors. There are two types of overloading in C++:
1. Function Overloading
2. Operator Overloading
1. Function Overloading
Function overloading allows you to define multiple functions with the same name but different
parameters.
Rules:
Example:
#include <iostream>
using namespace std;
// Function to add two integers
int add(int a, int b) {
return a + b;
}
int main() {
cout << add(5, 10) << endl; // Output: 15 (calls int add(int, int))
cout << add(5, 10, 15) << endl; // Output: 30 (calls int add(int, int, int))
cout << add(3.5, 2.5) << endl; // Output: 6.0 (calls double add(double, double))
return 0;
}
2. Operator Overloading
Operator overloading allows you to define custom behavior for operators when used with user-
defined types (e.g., classes).
Syntax:
return_type operator symbol (parameters) {
// Custom behavior
}
Example:
#include <iostream>
using namespace std;
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
int main() {
Complex c1(3, 4), c2(1, 2);
Complex c3 = c1 + c2; // Uses overloaded + operator
cout << c3 << endl; // Output: 4 + 6i
return 0;
}
<< Output (insertion) ostream& operator << (ostream& out, const Complex& obj)
>> Input (extraction) istream& operator >> (istream& in, Complex& obj)
void display() {
cout << "Count: " << count << endl;
}
};
int main() {
Counter c1(5);
Counter c2 = ++c1; // Prefix
c2.display(); // Output: Count: 6
Example:
class MyString {
private:
char* str;
public:
MyString(const char* s = "") {
str = new char[strlen(s) + 1];
strcpy(str, s);
}
void display() {
cout << str << endl;
}
~MyString() {
delete[] str;
}
};
int main() {
MyString s1("Hello"), s2;
s2 = s1; // Uses overloaded = operator
s2.display(); // Output: Hello
return 0;
}
6. Best Practices
1. Use function overloading to provide multiple ways to perform similar tasks.
2. Use operator overloading to make user-defined types behave like built-in types.
3. Avoid overloading operators in a way that makes the code less intuitive.
4. Always handle self-assignment when overloading the assignment operator.
26. Polymorphism
Polymorphism in C++
Polymorphism is a core concept in Object-Oriented Programming (OOP) that allows objects
of different classes to be treated as objects of a common base class. It enables flexibility and
extensibility in code by allowing a single interface to represent different underlying forms (data
types).
1. Types of Polymorphism
2. Compile-Time Polymorphism
a) Function Overloading
Example:
#include <iostream>
using namespace std;
void print(int i) {
cout << "Integer: " << i << endl;
}
void print(double d) {
cout << "Double: " << d << endl;
}
int main() {
print(5); // Output: Integer: 5
print(3.14); // Output: Double: 3.14
return 0;
}
b) Operator Overloading
• Defining custom behavior for operators when used with user-defined types.
Example:
#include <iostream>
using namespace std;
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
void display() {
cout << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(3, 4), c2(1, 2);
Complex c3 = c1 + c2; // Uses overloaded + operator
c3.display(); // Output: 4 + 6i
return 0;
}
3. Run-Time Polymorphism
Run-time polymorphism is achieved using virtual functions and function overriding.
a) Function Overriding
Example:
#include <iostream>
using namespace std;
class Animal {
public:
virtual void sound() {
cout << "Animal sound" << endl;
}
};
int main() {
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
delete animal1;
delete animal2;
return 0;
}
b) Virtual Functions
Example:
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() {
cout << "Drawing a shape" << endl;
}
};
int main() {
Shape* shape1 = new Circle();
Shape* shape2 = new Square();
delete shape1;
delete shape2;
return 0;
}
Syntax:
virtual return_type function_name() = 0;
Example:
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() = 0; // Pure virtual function
};
int main() {
Shape* shape1 = new Circle();
Shape* shape2 = new Square();
delete shape1;
delete shape2;
return 0;
}
5. Virtual Destructors
• If a base class pointer points to a derived class object, the base class destructor will be
called when the object is deleted, leading to memory leaks.
• To avoid this, declare the base class destructor as virtual.
Example:
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() {
cout << "Base destructor" << endl;
}
};
int main() {
Base* obj = new Derived();
delete obj; // Calls both Derived and Base destructors
return 0;
}
Output:
Derived destructor
Base destructor
6. Best Practices
Example:
class Employee {
private:
string name; // Private data member
int salary; // Private data member
public:
// Public methods to access private data
void setName(string n) {
name = n;
}
string getName() {
return name;
}
void setSalary(int s) {
salary = s;
}
int getSalary() {
return salary;
}
};
An abstract class is a class that cannot be instantiated and is meant to be inherited. It contains
at least one pure virtual function.
Syntax:
virtual return_type function_name() = 0;
Example:
#include <iostream>
using namespace std;
// Abstract class
class Shape {
public:
// Pure virtual function
virtual void draw() = 0;
};
// Derived class
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing a circle" << endl;
}
};
// Derived class
class Square : public Shape {
public:
void draw() override {
cout << "Drawing a square" << endl;
}
};
int main() {
Shape* shape1 = new Circle();
Shape* shape2 = new Square();
delete shape1;
delete shape2;
return 0;
}
class BankAccount {
private:
string accountNumber;
double balance;
public:
// Constructor
BankAccount(string accNum, double bal) : accountNumber(accNum), balance(bal) {}
int main() {
BankAccount acc("123456789", 1000);
acc.deposit(500);
cout << "Balance after deposit: $" << acc.getBalance() << endl;
acc.withdraw(200);
cout << "Balance after withdrawal: $" << acc.getBalance() << endl;
6. Best Practices
1. Use Access Specifiers:
o Declare data members as private to enforce encapsulation and abstraction.
2. Provide Public Methods:
o Expose only the necessary methods to interact with the class.
3. Use Abstract Classes:
o Define interfaces using abstract classes and pure virtual functions.
4. Hide Implementation Details:
o Avoid exposing internal logic and data structures.
2. Access Specifiers
C++ provides three access specifiers to control the visibility of class members:
Example:
class Employee {
private:
string name; // Private data member
int salary; // Private data member
public:
// Public methods to access private data
void setName(string n) {
name = n;
}
string getName() {
return name;
}
void setSalary(int s) {
salary = s;
}
int getSalary() {
return salary;
}
};
Example:
#include <iostream>
using namespace std;
class Employee {
private:
string name;
int salary;
public:
// Setter for name
void setName(string n) {
name = n;
}
int main() {
Employee emp;
emp.setName("John Doe");
emp.setSalary(50000);
class BankAccount {
private:
string accountNumber;
double balance;
public:
// Constructor
BankAccount(string accNum, double bal) : accountNumber(accNum), balance(bal) {}
int main() {
BankAccount acc("123456789", 1000);
acc.deposit(500);
cout << "Balance after deposit: $" << acc.getBalance() << endl;
acc.withdraw(200);
cout << "Balance after withdrawal: $" << acc.getBalance() << endl;
6. Best Practices
1. Make Data Members Private:
o Always declare data members as private to enforce encapsulation.
2. Use Getters and Setters:
o Provide public methods to access and modify private data members.
3. Validate Data:
o Use setters to validate data before modifying private members.
4. Avoid Exposing Implementation Details:
o Expose only the necessary methods and hide the internal logic.
29. Interfaces
Interfaces in C++
In C++, interfaces are implemented using abstract classes with pure virtual functions. An
interface defines a contract that derived classes must follow by implementing all the pure virtual
functions. Interfaces are used to achieve abstraction and polymorphism.
1. What is an Interface?
Syntax:
class InterfaceName {
public:
virtual return_type function_name() = 0; // Pure virtual function
};
2. Creating an Interface
To create an interface:
Example:
#include <iostream>
using namespace std;
// Interface
class Drawable {
public:
virtual void draw() = 0; // Pure virtual function
};
int main() {
Drawable* shape1 = new Circle();
Drawable* shape2 = new Square();
delete shape1;
delete shape2;
return 0;
}
3. Multiple Interfaces
A class can implement multiple interfaces by inheriting from multiple abstract classes.
Example:
#include <iostream>
using namespace std;
// First interface
class Drawable {
public:
virtual void draw() = 0;
};
// Second interface
class Resizable {
public:
virtual void resize(int factor) = 0;
};
int main() {
Circle circle;
circle.draw(); // Output: Drawing a circle
circle.resize(2); // Output: Resizing circle by factor 2
return 0;
}
4. Benefits of Interfaces
1. Abstraction:
o Hides implementation details and exposes only the functionality.
2. Polymorphism:
o Allows objects of different classes to be treated as objects of a common interface.
3. Flexibility:
o Enables loose coupling between classes.
4. Reusability:
o Interfaces can be reused across different parts of the program.
int main() {
PaymentMethod* payment1 = new CreditCard();
PaymentMethod* payment2 = new PayPal();
delete payment1;
delete payment2;
return 0;
}
6. Best Practices
Files and streams are used to handle input and output operations in C++. The <fstream> library
provides classes for working with files, while the <iostream> library handles standard input/output
streams.
b) Closing a File
int main() {
ofstream outFile;
outFile.open("example.txt", ios::out); // Open file for writing
if (outFile.is_open()) {
outFile << "Hello, File!" << endl;
outFile.close(); // Close the file
} else {
cout << "Unable to open file!" << endl;
}
return 0;
}
3. Writing to a File
Use the ofstream class to write data to a file.
Example:
#include <fstream>
using namespace std;
int main() {
ofstream outFile("example.txt");
if (outFile.is_open()) {
outFile << "This is line 1." << endl;
outFile << "This is line 2." << endl;
outFile.close();
} else {
cout << "Unable to open file!" << endl;
}
return 0;
}
Example:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream inFile("example.txt");
string line;
if (inFile.is_open()) {
while (getline(inFile, line)) {
cout << line << endl;
}
inFile.close();
} else {
cout << "Unable to open file!" << endl;
}
return 0;
}
5. File Modes
Mode Description
Example:
ofstream outFile("example.txt", ios::out | ios::app); // Open for appending
Binary files store data in binary format, which is more efficient for non-text data.
int main() {
ofstream outFile("data.bin", ios::binary);
if (outFile.is_open()) {
int data = 12345;
outFile.write((char*)&data, sizeof(data)); // Write binary data
outFile.close();
} else {
cout << "Unable to open file!" << endl;
}
return 0;
}
b) Reading from a Binary File
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream inFile("data.bin", ios::binary);
if (inFile.is_open()) {
int data;
inFile.read((char*)&data, sizeof(data)); // Read binary data
cout << "Data: " << data << endl;
inFile.close();
} else {
cout << "Unable to open file!" << endl;
}
return 0;
}
File position pointers track the current position in a file. You can manipulate them using:
Example:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
fstream file("example.txt", ios::in | ios::out);
if (file.is_open()) {
file << "Hello, World!" << endl;
string line;
getline(file, line);
cout << "First line: " << line << endl;
file.close();
} else {
cout << "Unable to open file!" << endl;
}
return 0;
}
8. Error Handling
Example:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream inFile("nonexistent.txt");
if (!inFile) {
cout << "Error: File not found!" << endl;
} else {
string line;
while (getline(inFile, line)) {
cout << line << endl;
}
inFile.close();
}
return 0;
}
9. Best Practices
1. Exception:
o An abnormal condition that occurs during program execution (e.g., division by
zero, file not found).
2. Try Block:
o A block of code where exceptions may occur. It is followed by one or more catch
blocks.
3. Catch Block:
o A block of code that handles exceptions thrown by the try block.
4. Throw Statement:
o Used to raise an exception explicitly.
2. Basic Syntax
try {
// Code that may throw an exception
if (errorCondition) {
throw exception; // Throw an exception
}
} catch (exceptionType& e) {
// Handle the exception
}
int main() {
int numerator, denominator;
cout << "Enter numerator and denominator: ";
cin >> numerator >> denominator;
try {
if (denominator == 0) {
throw "Division by zero error!"; // Throw a string exception
}
cout << "Result: " << numerator / denominator << endl;
} catch (const char* e) {
cout << "Error: " << e << endl;
}
return 0;
}
4. Standard Exceptions
C++ provides a set of standard exception classes in the <stdexcept> header. These include:
• std::runtime_error
• std::logic_error
• std::out_of_range
• std::invalid_argument
Example:
#include <iostream>
#include <stdexcept>
using namespace std;
int main() {
try {
throw runtime_error("A runtime error occurred!");
} catch (const runtime_error& e) {
cout << "Caught exception: " << e.what() << endl;
}
return 0;
}
Example:
#include <iostream>
using namespace std;
int main() {
try {
int choice;
cout << "Enter 1 for int, 2 for double, 3 for string: ";
cin >> choice;
if (choice == 1) {
throw 42; // Throw an int
} else if (choice == 2) {
throw 3.14; // Throw a double
} else if (choice == 3) {
throw string("Hello"); // Throw a string
} else {
throw invalid_argument("Invalid choice!"); // Throw a standard exception
}
} catch (int e) {
cout << "Caught int: " << e << endl;
} catch (double e) {
cout << "Caught double: " << e << endl;
} catch (const string& e) {
cout << "Caught string: " << e << endl;
} catch (const invalid_argument& e) {
cout << "Caught exception: " << e.what() << endl;
}
return 0;
}
6. Rethrowing Exceptions
You can rethrow an exception in a catch block to pass it to an outer try-catch block.
Example:
#include <iostream>
using namespace std;
void innerFunction() {
try {
throw runtime_error("Error in inner function!");
} catch (const runtime_error& e) {
cout << "Inner function caught: " << e.what() << endl;
throw; // Rethrow the exception
}
}
int main() {
try {
innerFunction();
} catch (const runtime_error& e) {
cout << "Main function caught: " << e.what() << endl;
}
return 0;
}
Example:
#include <iostream>
#include <exception>
using namespace std;
int main() {
try {
throw MyException();
} catch (const MyException& e) {
cout << "Caught exception: " << e.what() << endl;
}
return 0;
}
8. Best Practices
int main() {
try {
readFile("nonexistent.txt");
} catch (const runtime_error& e) {
cout << "Error: " << e.what() << endl;
}
return 0;
}
32. Dynamic Memory
Dynamic Memory in C++
Dynamic memory allocation allows you to allocate memory at runtime instead of compile time.
This is useful when the amount of memory needed is not known in advance or when you need to
manage memory manually.
Syntax:
pointer = new data_type; // Allocate memory for a single element
pointer = new data_type[size]; // Allocate memory for an array
int main() {
int* ptr = new int; // Allocate memory for an integer
*ptr = 42; // Assign a value
cout << "Value: " << *ptr << endl; // Output: Value: 42
delete ptr; // Deallocate memory
return 0;
}
int main() {
int size = 5;
int* arr = new int[size]; // Allocate memory for an array
4. Common Pitfalls
1. Memory Leaks:
o Forgetting to deallocate memory using delete or delete[].
2. int* ptr = new int;
3. // Forgot to delete ptr;
4. Dangling Pointers:
o Using a pointer after the memory it points to has been deallocated.
5. int* ptr = new int;
6. delete ptr;
7. *ptr = 10; // Undefined behavior
8. Double Deletion:
o Deallocating the same memory block twice.
9. int* ptr = new int;
10. delete ptr;
11. delete ptr; // Undefined behavior
Smart pointers automatically manage dynamic memory, preventing memory leaks and dangling
pointers. The <memory> header provides three types of smart pointers:
Example:
#include <iostream>
#include <memory> // For smart pointers
using namespace std;
int main() {
// Unique pointer
unique_ptr<int> ptr1(new int(42));
cout << "Value: " << *ptr1 << endl; // Output: Value: 42
// Shared pointer
shared_ptr<int> ptr2(new int(100));
cout << "Value: " << *ptr2 << endl; // Output: Value: 100
// Weak pointer
weak_ptr<int> ptr3 = ptr2;
if (auto sharedPtr = ptr3.lock()) {
cout << "Value: " << *sharedPtr << endl; // Output: Value: 100
}
Example:
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() {
cout << "Constructor called!" << endl;
}
~MyClass() {
cout << "Destructor called!" << endl;
}
void display() {
cout << "Hello, World!" << endl;
}
};
int main() {
MyClass* obj = new MyClass(); // Allocate memory for an object
obj->display(); // Output: Hello, World!
delete obj; // Deallocate memory
return 0;
}
7. Best Practices
int main() {
int size = 1000000000; // Very large size
int* arr = new (nothrow) int[size]; // Allocate memory without throwing an exception
if (!arr) {
cout << "Memory allocation failed!" << endl;
} else {
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
}
delete[] arr; // Deallocate memory
}
return 0;
}
33. Namespaces
Namespaces in C++
Namespaces are used to organize code and prevent name conflicts in large programs. They
allow you to group related classes, functions, and variables under a unique name.
1. Defining a Namespace
Use the namespace keyword to define a namespace.
Syntax:
namespace NamespaceName {
// Classes, functions, variables, etc.
}
Example:
#include <iostream>
using namespace std;
namespace Math {
int add(int a, int b) {
return a + b;
}
}
int main() {
cout << Math::add(5, 10) << endl; // Output: 15
return 0;
}
You can access namespace members using the scope resolution operator (::).
Example:
#include <iostream>
using namespace std;
namespace Math {
int add(int a, int b) {
return a + b;
}
}
int main() {
int result = Math::add(5, 10); // Access using ::
cout << "Result: " << result << endl; // Output: Result: 15
return 0;
}
The using directive allows you to bring all members of a namespace into the current scope.
Example:
#include <iostream>
using namespace std;
namespace Math {
int add(int a, int b) {
return a + b;
}
}
using namespace Math; // Bring all Math members into the current scope
int main() {
cout << add(5, 10) << endl; // Output: 15
return 0;
}
4. Nested Namespaces
Namespaces can be nested inside other namespaces.
Example:
#include <iostream>
using namespace std;
namespace Outer {
namespace Inner {
void display() {
cout << "Inside Inner namespace" << endl;
}
}
}
int main() {
Outer::Inner::display(); // Output: Inside Inner namespace
return 0;
}
5. Anonymous Namespaces
An anonymous namespace is a namespace without a name. Its members have internal linkage,
meaning they are only accessible within the same file.
Example:
#include <iostream>
using namespace std;
namespace {
void display() {
cout << "Inside anonymous namespace" << endl;
}
}
int main() {
display(); // Output: Inside anonymous namespace
return 0;
}
6. Namespace Aliases
Example:
#include <iostream>
using namespace std;
namespace VeryLongNamespaceName {
void display() {
cout << "Inside VeryLongNamespaceName" << endl;
}
}
namespace VLN = VeryLongNamespaceName; // Create an alias
int main() {
VLN::display(); // Output: Inside VeryLongNamespaceName
return 0;
}
The std namespace contains all the standard C++ library components (e.g., cout, cin, vector).
Example:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> nums = {1, 2, 3};
for (int num : nums) {
cout << num << " "; // Output: 1 2 3
}
return 0;
}
8. Best Practices
1. Avoid using namespace std:
o Prefer using std:: explicitly to avoid name conflicts.
2. Use Namespaces to Organize Code:
o Group related classes, functions, and variables under meaningful namespaces.
3. Avoid Global Namespaces:
o Minimize the use of the global namespace to prevent name clashes.
4. Use Namespace Aliases:
o Simplify long namespace names with aliases.
namespace MyLibrary {
namespace Math {
int add(int a, int b) {
return a + b;
}
}
namespace String {
string reverse(string str) {
return string(str.rbegin(), str.rend());
}
}
}
int main() {
cout << MyLibrary::Math::add(5, 10) << endl; // Output: 15
cout << MyLibrary::String::reverse("Hello") << endl; // Output: olleH
return 0;
}
34. Templates
Templates in C++
Templates are a powerful feature in C++ that allow you to write generic and reusable code.
They enable you to define functions and classes that work with any data type.
1. Function Templates
A function template allows you to define a function that can operate on different data types.
Syntax:
template <typename T>
return_type function_name(parameters) {
// Function body
}
Example:
#include <iostream>
using namespace std;
int main() {
cout << add(5, 10) << endl; // Output: 15 (int)
cout << add(3.5, 2.5) << endl; // Output: 6.0 (double)
cout << add(string("Hello, "), string("World!")) << endl; // Output: Hello, World! (string)
return 0;
}
2. Class Templates
A class template allows you to define a class that can work with different data types.
Syntax:
template <typename T>
class ClassName {
// Class members
};
Example:
#include <iostream>
using namespace std;
int main() {
Box<int> intBox(42);
Box<string> strBox("Hello");
cout << "Int Box: " << intBox.getValue() << endl; // Output: Int Box: 42
cout << "String Box: " << strBox.getValue() << endl; // Output: String Box: Hello
return 0;
}
Example:
#include <iostream>
using namespace std;
int main() {
printPair(5, 3.14); // Output: (5, 3.14)
printPair("Hello", 42); // Output: (Hello, 42)
return 0;
}
4. Template Specialization
Example:
#include <iostream>
using namespace std;
// General template
template <typename T>
void printType(T value) {
cout << "Generic: " << value << endl;
}
int main() {
printType(3.14); // Output: Generic: 3.14
printType(42); // Output: Specialized for int: 42
return 0;
}
Example:
#include <iostream>
using namespace std;
Variadic templates allow you to define templates that accept a variable number of arguments.
Example:
#include <iostream>
using namespace std;
// Variadic template
template <typename T, typename... Args>
void print(T first, Args... args) {
cout << first << endl;
print(args...); // Recursive call
}
int main() {
print(1, 3.14, "Hello", 42); // Output: 1, 3.14, Hello, 42, End of list
return 0;
}
7. Best Practices
T pop() {
if (top >= 0) {
return arr[top--];
} else {
cout << "Stack underflow!" << endl;
return T(); // Return default value
}
}
};
int main() {
Stack<int, 5> intStack;
intStack.push(10);
intStack.push(20);
cout << "Popped: " << intStack.pop() << endl; // Output: Popped: 20
cout << "Popped: " << intStack.pop() << endl; // Output: Popped: 10
return 0;
}
35. Preprocessor
Preprocessor in C++
The preprocessor is a tool that processes the source code before it is compiled. It performs tasks
like including files, defining macros, and conditional compilation. Preprocessor directives
begin with a # symbol.
2. #include Directive
The #include directive is used to include the contents of a file in the source code.
Example:
#include <iostream> // Include the standard iostream library
using namespace std;
int main() {
cout << "Hello, World!" << endl;
return 0;
}
3. #define Directive
The #define directive is used to define macros, which are replaced by the preprocessor before
compilation.
Example:
#include <iostream>
using namespace std;
int main() {
cout << "Value of PI: " << PI << endl; // Output: Value of PI: 3.14159
return 0;
}
Example:
#include <iostream>
using namespace std;
#define SQUARE(x) ((x) * (x)) // Macro with argument
int main() {
cout << "Square of 5: " << SQUARE(5) << endl; // Output: Square of 5: 25
return 0;
}
5. Conditional Compilation
Conditional compilation allows you to include or exclude code based on certain conditions.
Example:
#include <iostream>
using namespace std;
int main() {
#ifdef DEBUG
cout << "Debug mode is on!" << endl; // Output: Debug mode is on!
#else
cout << "Debug mode is off!" << endl;
#endif
return 0;
}
Example:
#include <iostream>
using namespace std;
#define VERSION 2
int main() {
#if VERSION == 1
cout << "Version 1" << endl;
#elif VERSION == 2
cout << "Version 2" << endl; // Output: Version 2
#else
cout << "Unknown version" << endl;
#endif
return 0;
}
7. #pragma Directive
Example:
#include <iostream>
using namespace std;
int main() {
cout << "Hello, World!" << endl;
return 0;
}
8. #undef Directive
Example:
#include <iostream>
using namespace std;
#define DEBUG
int main() {
#ifdef DEBUG
cout << "Debug mode is on!" << endl; // Output: Debug mode is on!
#endif
#ifdef DEBUG
cout << "Debug mode is still on!" << endl;
#else
cout << "Debug mode is off!" << endl; // Output: Debug mode is off!
#endif
return 0;
}
9. Predefined Macros
C++ provides several predefined macros that give information about the compilation
environment.
Macro Description
__LINE__ Current line number.
Example:
#include <iostream>
using namespace std;
int main() {
cout << "Line: " << __LINE__ << endl; // Output: Line: 6
cout << "File: " << __FILE__ << endl; // Output: File: [filename]
cout << "Date: " << __DATE__ << endl; // Output: Date: [current date]
cout << "Time: " << __TIME__ << endl; // Output: Time: [current time]
cout << "C++ Version: " << __cplusplus << endl; // Output: C++ Version: [version]
return 0;
}
#ifdef DEBUG
#define LOG(msg) cout << "DEBUG: " << msg << endl
#else
#define LOG(msg) // Define LOG as nothing in non-debug mode
#endif
int main() {
LOG("Starting program..."); // Output: DEBUG: Starting program...
cout << "Hello, World!" << endl;
LOG("Ending program..."); // Output: DEBUG: Ending program...
return 0;
}
Signal handling is a mechanism to handle asynchronous events (signals) that occur during
program execution, such as interrupts or exceptions. C++ provides the <csignal> library to
handle signals.
1. Common Signals
Signal Description
2. Handling Signals
Syntax:
void (*signal(int sig, void (*handler)(int)))(int);
Example:
#include <iostream>
#include <csignal>
using namespace std;
// Signal handler function
void signalHandler(int signum) {
cout << "Interrupt signal (" << signum << ") received." << endl;
exit(signum); // Terminate program
}
int main() {
// Register signal handler for SIGINT
signal(SIGINT, signalHandler);
while (true) {
cout << "Press Ctrl+C to exit..." << endl;
sleep(1); // Simulate work
}
return 0;
}
3. Raising Signals
Syntax:
int raise(int sig);
Example:
#include <iostream>
#include <csignal>
using namespace std;
int main() {
signal(SIGINT, signalHandler);
return 0;
}
4. Ignoring Signals
Example:
#include <iostream>
#include <csignal>
using namespace std;
int main() {
// Ignore SIGINT
signal(SIGINT, SIG_IGN);
return 0;
}
Example:
#include <iostream>
#include <csignal>
using namespace std;
int main() {
signal(SIGINT, signalHandler);
cout << "Press Ctrl+C once to trigger custom handler, then again to terminate." << endl;
while (true) {
// Infinite loop
}
return 0;
}
Example:
#include <iostream>
#include <csignal>
using namespace std;
int main() {
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
cout << "Press Ctrl+C or send SIGTERM to test signal handling..." << endl;
while (true) {
// Infinite loop
}
return 0;
}
7. Best Practices
atomic<bool> shutdownFlag(false);
cout << "Press Ctrl+C or send SIGTERM to initiate shutdown..." << endl;
while (!shutdownFlag) {
// Simulate work
}
37. Multithreading
Multithreading is a powerful feature in C++ that allows you to execute multiple threads
concurrently, enabling better utilization of CPU resources and improving the performance of
applications, especially those that perform I/O operations or need to handle multiple tasks
simultaneously.
Multithreading in C++
C++ provides multithreading support through the <thread> library, introduced in C++11. Below
are the key components and techniques for working with threads in C++.
1. Creating Threads
You can create a thread using the std::thread class. The thread starts executing as soon as it is
created.
Example:
#include <iostream>
#include <thread>
using namespace std;
void task() {
cout << "Thread is running!" << endl;
}
int main() {
thread t1(task); // Create a thread that executes the task function
t1.join(); // Wait for the thread to finish
cout << "Main thread continues..." << endl;
return 0;
}
Explanation:
Example:
#include <iostream>
#include <thread>
using namespace std;
int main() {
thread t1(printMessage, "Hello from thread!");
t1.join();
return 0;
}
3. Detaching Threads
A thread can be detached using the detach() method. A detached thread runs independently, and
the main thread does not wait for it to finish.
Example:
#include <iostream>
#include <thread>
using namespace std;
void task() {
cout << "Thread is running!" << endl;
}
int main() {
thread t1(task);
t1.detach(); // Detach the thread
cout << "Main thread continues..." << endl;
// The program may terminate before the thread finishes
return 0;
}
4. Thread Synchronization
When multiple threads access shared resources, synchronization is required to avoid race
conditions. C++ provides several synchronization mechanisms:
int main() {
thread t1(printNumbers, 1);
thread t2(printNumbers, 2);
t1.join();
t2.join();
return 0;
}
5. Race Conditions
A race condition occurs when multiple threads access shared data simultaneously, leading to
unpredictable results.
int sharedValue = 0;
void increment() {
for (int i = 0; i < 100000; i++) {
sharedValue++;
}
}
int main() {
thread t1(increment);
thread t2(increment);
t1.join();
t2.join();
cout << "Final value: " << sharedValue << endl; // May not be 200000
return 0;
}
Fixing the Race Condition with Mutex
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
int sharedValue = 0;
mutex mtx;
void increment() {
for (int i = 0; i < 100000; i++) {
lock_guard<mutex> lock(mtx);
sharedValue++;
}
}
int main() {
thread t1(increment);
thread t2(increment);
t1.join();
t2.join();
cout << "Final value: " << sharedValue << endl; // Will be 200000
return 0;
}
6. Condition Variables
Condition variables are used to block threads until a specific condition is met. They are often
used with mutexes.
queue<int> buffer;
mutex mtx;
condition_variable cv;
const int maxSize = 5;
int main() {
thread p1(producer, 1);
thread c1(consumer, 1);
p1.join();
c1.join();
return 0;
}
7. Thread Safety
8. Thread Pooling
Thread pooling is a technique where a fixed number of threads are created to handle tasks. This
avoids the overhead of creating and destroying threads repeatedly.
class ThreadPool {
public:
ThreadPool(size_t numThreads) {
for (size_t i = 0; i < numThreads; i++) {
workers.emplace_back([this] {
while (true) {
function<void()> task;
{
unique_lock<mutex> lock(queueMutex);
cv.wait(lock, [this] { return !tasks.empty() || stop; });
if (stop && tasks.empty()) return;
task = move(tasks.front());
tasks.pop();
}
task();
}
});
}
}
~ThreadPool() {
{
unique_lock<mutex> lock(queueMutex);
stop = true;
}
cv.notify_all();
for (thread& worker : workers) {
worker.join();
}
}
private:
vector<thread> workers;
queue<function<void()>> tasks;
mutex queueMutex;
condition_variable cv;
bool stop = false;
};
int main() {
ThreadPool pool(4);
return 0;
}
int main() {
cout << "Content-type:text/html\r\n\r\n";
cout << "<html><body><h1>Hello, World!</h1></body></html>";
return 0;
}
39. STL Tutorial
The Standard Template Library (STL) is a powerful library in C++ that provides a collection
of template classes and functions for common data structures and algorithms. It is a core part of
the C++ Standard Library and is widely used for efficient and reusable code.
1. Containers
Containers are data structures that store collections of objects. STL provides several types of
containers:
Sequence Containers
• std::vector: Dynamic array.
• std::list: Doubly linked list.
• std::deque: Double-ended queue.
• std::array: Fixed-size array (introduced in C++11).
Associative Containers
Unordered Containers
2. Algorithms
STL provides a wide range of algorithms that operate on containers. These include:
3. Iterators
Iterators are used to traverse elements in containers. They act as pointers to container elements.
Common iterator types include:
4. Functors
Functors are objects that can be used as if they were functions. They are often used as arguments
to algorithms.
STL Examples
1. Vector (std::vector)
A dynamic array that can resize itself automatically.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> numbers = {1, 2, 3, 4, 5};
// Add elements
numbers.push_back(6);
// Access elements
cout << "First element: " << numbers[0] << endl;
return 0;
}
2. Map (std::map)
#include <iostream>
#include <map>
using namespace std;
int main() {
map<string, int> ages;
// Insert elements
ages["Alice"] = 25;
ages["Bob"] = 30;
// Access elements
cout << "Alice's age: " << ages["Alice"] << endl;
return 0;
}
3. Set (std::set)
A collection of unique keys, sorted by keys.
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> numbers = {3, 1, 4, 1, 5, 9}; // Duplicates are ignored
// Insert elements
numbers.insert(2);
return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> numbers = {5, 3, 1, 4, 2};
// Find an element
auto it = find(numbers.begin(), numbers.end(), 3);
if (it != numbers.end()) {
cout << "Found 3 at position: " << distance(numbers.begin(), it) << endl;
}
return 0;
}
5. Stack (std::stack)
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> s;
// Push elements
s.push(10);
s.push(20);
s.push(30);
// Pop elements
while (!s.empty()) {
cout << s.top() << " "; // Access the top element
s.pop(); // Remove the top element
}
cout << endl;
return 0;
}
6. Queue (std::queue)
#include <iostream>
#include <queue>
using namespace std;
int main() {
queue<int> q;
// Push elements
q.push(10);
q.push(20);
q.push(30);
// Pop elements
while (!q.empty()) {
cout << q.front() << " "; // Access the front element
q.pop(); // Remove the front element
}
cout << endl;
return 0;
}
7. Priority Queue (std::priority_queue)
#include <iostream>
#include <queue>
using namespace std;
int main() {
priority_queue<int> pq;
// Push elements
pq.push(30);
pq.push(10);
pq.push(20);
return 0;
}
8. Iterators
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> numbers = {1, 2, 3, 4, 5};
return 0;
}
9. Functors
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Square {
int operator()(int x) const {
return x * x;
}
};
int main() {
vector<int> numbers = {1, 2, 3, 4, 5};
return 0;
}
The C++ Standard Library is a collection of classes and functions that provide essential
functionality for C++ programs. It includes the Standard Template Library (STL),
input/output (I/O) facilities, string manipulation, mathematical functions, and more. Below is a
detailed tutorial on the key components of the C++ Standard Library.
Key Components of the C++ Standard Library
1. Containers: Data structures like vector, list, map, etc.
2. Algorithms: Functions like sort, find, copy, etc.
3. Iterators: Used to traverse containers.
4. Input/Output (I/O): Classes like cin, cout, ifstream, ofstream.
5. Strings: The std::string class for string manipulation.
6. Numerics: Mathematical functions and utilities.
7. Utilities: General-purpose utilities like std::pair, std::tuple, and std::function.
8. Smart Pointers: Memory management utilities like std::unique_ptr and std::shared_ptr.
9. Multithreading: Threading support with std::thread, std::mutex, etc.
10. Time Utilities: Time-related functions and classes like std::chrono.
1. Containers
Containers are data structures that store collections of objects. The most commonly used
containers are:
Sequence Containers
Example: std::vector
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> numbers = {1, 2, 3, 4, 5};
// Add elements
numbers.push_back(6);
// Access elements
cout << "First element: " << numbers[0] << endl;
Associative Containers
Example: std::map
#include <iostream>
#include <map>
using namespace std;
int main() {
map<string, int> ages;
// Insert elements
ages["Alice"] = 25;
ages["Bob"] = 30;
// Access elements
cout << "Alice's age: " << ages["Alice"] << endl;
return 0;
}
Unordered Containers
Example: std::unordered_map
#include <iostream>
#include <unordered_map>
using namespace std;
int main() {
unordered_map<string, int> ages;
// Insert elements
ages["Alice"] = 25;
ages["Bob"] = 30;
// Access elements
cout << "Alice's age: " << ages["Alice"] << endl;
return 0;
}
2. Algorithms
STL provides a wide range of algorithms that operate on containers. These include:
Example: std::sort
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> numbers = {5, 3, 1, 4, 2};
return 0;
}
3. Input/Output (I/O)
The C++ Standard Library provides classes for input and output operations:
int main() {
// Write to a file
ofstream outFile("example.txt");
if (outFile.is_open()) {
outFile << "Hello, File!" << endl;
outFile.close();
}
return 0;
}
4. Strings
The std::string class provides powerful string manipulation capabilities.
Example: std::string
#include <iostream>
#include <string>
using namespace std;
int main() {
string str = "Hello, World!";
// Access characters
cout << "First character: " << str[0] << endl;
// Concatenate strings
string str2 = " How are you?";
string result = str + str2;
cout << result << endl;
// Find substring
size_t pos = str.find("World");
if (pos != string::npos) {
cout << "Found 'World' at position: " << pos << endl;
}
return 0;
}
5. Numerics
The C++ Standard Library provides mathematical functions and utilities.
int main() {
double x = 16.0;
cout << "Square root of " << x << ": " << sqrt(x) << endl;
cout << "2^3: " << pow(2, 3) << endl;
return 0;
}
6. Utilities
The Standard Library includes general-purpose utilities like std::pair, std::tuple, and std::function.
Example: std::pair
#include <iostream>
#include <utility>
using namespace std;
int main() {
pair<string, int> person("Alice", 25);
cout << "Name: " << person.first << ", Age: " << person.second << endl;
return 0;
}
7. Smart Pointers
Smart pointers automate memory management and prevent memory leaks.
Example: std::unique_ptr
#include <iostream>
#include <memory>
using namespace std;
int main() {
unique_ptr<int> ptr(new int(42));
cout << "Value: " << *ptr << endl;
// No need to delete; memory is automatically released
return 0;
}
8. Multithreading
The Standard Library provides support for multithreading.
Example: std::thread
#include <iostream>
#include <thread>
using namespace std;
void task() {
cout << "Thread is running!" << endl;
}
int main() {
thread t1(task);
t1.join(); // Wait for the thread to finish
cout << "Main thread continues..." << endl;
return 0;
}
9. Time Utilities
The std::chrono library provides time-related utilities.
Example: std::chrono
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
using namespace std::chrono;
int main() {
auto start = high_resolution_clock::now();
// Simulate work
this_thread::sleep_for(seconds(2));
cout << "Time taken: " << duration.count() << " milliseconds" << endl;
return 0;
}
Best Practices for Using the Standard Library
1. Use Containers Wisely: Choose the right container for your needs.
2. Leverage Algorithms: Use STL algorithms instead of writing manual loops.
3. Prefer Smart Pointers: Use std::unique_ptr and std::shared_ptr for memory management.
4. Use Standard Utilities: Take advantage of utilities like std::pair, std::tuple, and std::function.
5. Avoid Raw Pointers: Minimize the use of raw pointers to prevent memory leaks.
Definitions
• Source Code: Human-readable code written in a high-level language.
• Object Code: Machine-readable code produced by a compiler.
• Class: A blueprint for creating objects.
• Object: An instance of a class.
• Function: A block of code that performs a specific task.
Using Directive
• Advantages:
o Simplifies code by avoiding std:: prefix.
• Disadvantages:
o Can lead to naming conflicts and reduced clarity.
Inheritance Benefits
1. Code Reusability: Reduces redundancy.
2. Extensibility: Add new features to derived classes.
3. Maintainability: Changes in the base class propagate to derived classes.
Function Encapsulation
• Encapsulation: Hides implementation details, making code modular and easier to debug.
Polymorphism
• Polymorphism: Allows objects of different classes to be treated as objects of a common
superclass, enabling flexible and reusable code.
Increment Operators
• Prefix (++i): Increments before use.
• Postfix (i++): Increments after use.
Friend Functions
• Friend Functions: Can access private and protected members of a class, potentially
undermining encapsulation.
Program Examples
• Pointer to Memory Address:
int num = 62;
int* ptr = #
cout << "Memory address: " << ptr;
Conclusion
This guide covers everything in C++ from the basics to advanced topics, including exam-style
questions and practical examples. Practice coding regularly and revise these concepts to ace
your exam. Good luck!