Cpp
Cpp
Code Example:
#include <iostream>
using namespace std;
int main() {
int age;
cout << "Enter your age: ";
cin >> age; // Input from user
cout << "Your age is: " << age << endl; // Output to screen
return 0;
}
Explanation:
• cout displays the message to the user.
• cin takes the user’s input and stores it in the variable age.
Code Example:
#include <iostream>
using namespace std;
class Car {
public:
string model;
int year;
void displayDetails() {
cout << "Model: " << model << ", Year: " << year << endl;
}
};
int main() {
Car car1; // Creating an object of the class Car
car1.model = "Toyota";
car1.year = 2020;
return 0;
}
Explanation:
• Car is a class with two data members (model and year) and one member function
(displayDetails).
• car1 is an object of class Car.
Functions are blocks of code that perform specific tasks in a C++ program. They help in
breaking down complex tasks into simpler, reusable parts. C++ provides various types of
functions such as functions with default parameters, inline functions, function overloading,
and recursion, among others.
---
A function can have default values for its parameters. This allows you to call the function
without providing all the arguments. If arguments are omitted, the default values are used.
int main() {
greet(); // Uses default parameters
greet("Alice", 25); // Uses provided parameters
return 0;
}
```
**Explanation:**
- `greet` has default values for `name` and `age`.
- If the parameters are not provided during the function call, the default values are used.
---
An **inline function** is a function that is expanded in line at the point of call. It eliminates
the overhead of function calls by inserting the code of the function directly at the call site.
Inline functions are useful for small functions.
**Explanation:**
- `add` is an inline function, and instead of calling the function, its code is inserted directly at
the point of call.
---
Manipulator functions are used to modify the state of output streams. Some common
manipulators in C++ are `setw`, `setprecision`, `endl`, and `flush`.
int main() {
double pi = 3.14159265359;
---
void display(int a) {
cout << "Integer: " << a << endl;
}
void display(double a) {
cout << "Double: " << a << endl;
}
int main() {
display(5); // Calls display(int)
display(3.14); // Calls display(double)
return 0;
}
```
**Explanation:**
- Both `display` functions have the same name but different parameter types (int and double).
---
A **friend function** can access private and protected members of a class. Similarly, a
**friend class** can access the private and protected members of another class.
class Box {
private:
int length;
public:
Box() : length(10) {}
int main() {
Box box;
printLength(box); // Accessing private member through friend function
return 0;
}
```
**Explanation:**
- `printLength` is a friend function of `Box` and can access its private members.
class Box {
private:
int length;
public:
Box() : length(10) {}
int main() {
Box box;
BoxPrinter printer;
printer.print(box); // Accessing private member through friend class
return 0;
}
```
**Explanation:**
- `BoxPrinter` is a friend class of `Box` and can access its private members.
---
int main() {
int x = 10;
int &ref = x; // Reference variable
**Explanation:**
- `ref` is a reference variable, referring to `x`.
- Modifying `ref` also changes the value of `x`.
---
## **7. Differences between Call by Value, Call by Address, and Call by Reference**
void byValue(int a) {
a = 20; // Modifies only local copy
}
int main() {
int x = 10;
byValue(x);
cout << "After byValue: " << x << endl; // x remains 10
byAddress(&x);
cout << "After byAddress: " << x << endl; // x becomes 30
byReference(x);
cout << "After byReference: " << x << endl; // x becomes 40
return 0;
}
```
**Explanation:**
- **Call by Value** does not affect the original variable.
- **Call by Address** and **Call by Reference** both modify the original variable.
---
### **Recursion** occurs when a function calls itself. It is a powerful tool for solving
problems that can be broken down into smaller subproblems.
int factorial(int n) {
if (n <= 1) return 1; // Base case
else return n * factorial(n - 1); // Recursive call
}
class Math {
public:
int fibonacci(int n) {
if (n <= 1) return n; // Base case
else return fibonacci(n - 1) + fibonacci(n - 2); // Recursive call
}
};
int main() {
int num = 5;
cout << "Factorial of " << num << ": " << factorial(num) << endl;
Math math;
cout << "Fibonacci of " << num << ": " << math.fibonacci(num) << endl;
return 0;
}
```
**Explanation:**
- The **`factorial`** function is a simple recursive function.
- The **`fibonacci`** function is a recursive member function of the `Math` class.
---
| Concept | Description |
|----------------------------------|-----------------------------------------------------------------------------|
| **Default Parameters** | Functions with default values for parameters.
|
| **Inline Functions** | Functions expanded at the call site to eliminate function call
overhead. |
| **Function Overloading** | Functions with the same name but different parameters.
|
| **Friend Function/Class** | Functions/classes that can access private members of other
classes. |
| **Reference Variables** | Aliases for other variables. |
| **Call by Value, Address, Ref** | Different methods of passing arguments to functions.
|
| **Recursion** | Functions that call themselves to solve smaller
#include <iostream>
using namespace std;
class Person {
private:
string name;
public:
void setName(string n) {
name = n;
}
string getName() {
return name;
}
};
int main() {
Person person1;
person1.setName("John");
cout << "Name: " << person1.getName() << endl;
return 0;
}
Explanation:
• Private members are not directly accessible; we use public member functions (setName
and getName) to set and get the value.
Unions
A union allows storing different types of data in the same memory location. Only one member of a
union can hold a value at a time.
Enumerations
An enumeration (enum) is a user-defined type consisting of a set of named integer constants.
Code Example:
#include <iostream>
using namespace std;
struct Student {
string name;
int age;
};
union Data {
int i;
float f;
char c;
};
Data data1;
data1.i = 5;
cout << "Union Data: " << data1.i << endl;
Explanation:
• Student is a structure.
• Data is a union where only one of i, f, or c can be used at a time.
• Color is an enumeration.
Code Example:
#include <iostream>
using namespace std;
class Rectangle {
public:
int width, height;
// Inline function
inline int area() {
return width * height;
}
// Non-inline function
int perimeter() {
return 2 * (width + height);
}
};
int main() {
Rectangle rect;
rect.width = 10;
rect.height = 5;
cout << "Area: " << rect.area() << endl;
cout << "Perimeter: " << rect.perimeter() << endl;
return 0;
}
Explanation:
• The area function is inline, meaning it will be expanded in the place where it is called.
• The perimeter function is a non-inline function.
Code Example:
#include <iostream>
using namespace std;
class Counter {
public:
static int count; // Static data member
Counter() {
count++;
}
int main() {
Counter c1, c2;
Counter::showCount(); // Accessing static member function
return 0;
}
Explanation:
• count is a static data member, shared by all instances of Counter.
• showCount is a static member function that can be called using the class name.
7. Differences between Procedural and Object-Oriented
Programming Paradigms
Procedural Programming
• Focuses on functions and procedures that operate on data.
• Code is structured into functions.
• Examples: C, Fortran.
Key Differences:
• Procedure vs. Object: Procedural programming focuses on actions (functions), whereas
OOP focuses on entities (objects).
• Data Encapsulation: OOP encapsulates data within objects, whereas in procedural
programming, data is often global or passed between functions.
Code Example:
#include <iostream>
using namespace std;
int main() {
string name;
cout << "Enter your name: ";
getline(cin, name); // Read input with spaces
cout << "Hello, " << name << "!" << endl;
cerr << "This is an error message." << endl; // Used for error messages
clog << "This is a log message." << endl; // Used for logging
return 0;
}
Explanation:
• cin is used to get user input.
• cout is used to display output.
• cerr is used for error messages (outputs to the standard error stream).
• clog is used for logging information.
Summary Table
Concept Description
cin/cout Used for input/output operations.
Class and Object Classes define the structure of objects; objects are instances of classes.
Static Members Static data members and functions are shared among all objects of a class.
Inline Function Functions that are expanded inline to reduce overhead.
OOP focuses on objects, while procedural programming focuses on
OOP vs Procedural
functions.
I/O Streams Standard streams for input/output, such as cin, cout, cerr, and clog.
These concepts are foundational for understanding C++ and object-oriented programming (OOP).
Functions in C++
Functions are blocks of code that perform specific tasks in a C++ program. They help in breaking
down complex tasks into simpler, reusable parts. C++ provides various types of functions such as
functions with default parameters, inline functions, function overloading, and recursion, among
others.
Code Example:
#include <iostream>
using namespace std;
int main() {
greet(); // Uses default parameters
greet("Alice", 25); // Uses provided parameters
return 0;
}
Explanation:
• greet has default values for name and age.
• If the parameters are not provided during the function call, the default values are used.
2. Inline Functions
An inline function is a function that is expanded in line at the point of call. It eliminates the
overhead of function calls by inserting the code of the function directly at the call site. Inline
functions are useful for small functions.
Code Example:
#include <iostream>
using namespace std;
int main() {
cout << "Sum: " << add(5, 10) << endl;
return 0;
}
Explanation:
• add is an inline function, and instead of calling the function, its code is inserted directly at
the point of call.
3. Manipulator Functions
Manipulator functions are used to modify the state of output streams. Some common manipulators
in C++ are setw, setprecision, endl, and flush.
Code Example:
#include <iostream>
#include <iomanip> // For manipulators
using namespace std;
int main() {
double pi = 3.14159265359;
Explanation:
• setw(10) sets the width of the printed output to 10 characters.
• setprecision(4) sets the precision of floating-point numbers to 4 digits.
4. Function Overloading and Scope Rules
Function Overloading
Function overloading occurs when two or more functions have the same name but differ in the
number or type of parameters.
Code Example:
#include <iostream>
using namespace std;
void display(int a) {
cout << "Integer: " << a << endl;
}
void display(double a) {
cout << "Double: " << a << endl;
}
int main() {
display(5); // Calls display(int)
display(3.14); // Calls display(double)
return 0;
}
Explanation:
• Both display functions have the same name but different parameter types (int and
double).
Scope Rules
In C++, scope refers to the region where a variable or function can be accessed. There are different
types of scope:
• Local Scope: Inside a function.
• Global Scope: Outside all functions, accessible from anywhere in the program.
• Class Scope: Inside a class.
class Box {
private:
int length;
public:
Box() : length(10) {}
int main() {
Box box;
printLength(box); // Accessing private member through friend function
return 0;
}
Explanation:
• printLength is a friend function of Box and can access its private members.
class Box {
private:
int length;
public:
Box() : length(10) {}
class BoxPrinter {
public:
void print(Box b) {
cout << "Length: " << b.length << endl; // Accessing private member
}
};
int main() {
Box box;
BoxPrinter printer;
printer.print(box); // Accessing private member through friend class
return 0;
}
Explanation:
• BoxPrinter is a friend class of Box and can access its private members.
6. Reference Variables
A reference variable is an alias for another variable. Once a reference is initialized, it cannot be
changed to refer to a different variable.
Code Example:
#include <iostream>
using namespace std;
int main() {
int x = 10;
int &ref = x; // Reference variable
Explanation:
• ref is a reference variable, referring to x.
• Modifying ref also changes the value of x.
Call by Address:
• The address of the argument is passed, allowing the function to modify the original variable.
Call by Reference:
• A reference to the actual parameter is passed, allowing the function to directly modify the
original variable.
Code Example:
#include <iostream>
using namespace std;
void byValue(int a) {
a = 20; // Modifies only local copy
}
byValue(x);
cout << "After byValue: " << x << endl; // x remains 10
byAddress(&x);
cout << "After byAddress: " << x << endl; // x becomes 30
byReference(x);
cout << "After byReference: " << x << endl; // x becomes 40
return 0;
}
Explanation:
• Call by Value does not affect the original variable.
• Call by Address and Call by Reference both modify the original variable.
Code Example:
#include <iostream>
using namespace std;
int factorial(int n) {
if (n <= 1) return 1; // Base case
else return n * factorial(n - 1); // Recursive call
}
class Math {
public:
int fibonacci(int n) {
if (n <= 1) return n; // Base case
else return fibonacci(n - 1) + fibonacci(n - 2); // Recursive call
}
};
int main() {
int num = 5;
cout << "Factorial of " << num << ": " << factorial(num) << endl;
Math math;
cout << "Fibonacci of " << num << ": " << math.fibonacci(num) << endl;
return 0;
}
Explanation:
• The factorial function is a simple recursive function.
• The fibonacci function is a recursive member function of the Math class.
Summary Table
Concept Description
Default Parameters Functions with default values for parameters.
Functions expanded at the call site to eliminate function call
Inline Functions
overhead.
Function Overloading Functions with the same name but different parameters.
Friend Function/Class Functions/classes that can access private members of other classes.
Reference Variables Aliases for other variables.
Call by Value, Address, Ref Different methods of passing arguments to functions.
Recursion Functions that call themselves to solve smaller
UNIT 2
Pointers, Reference Variables, Arrays, and String Concepts in C++
In C++, pointers are variables that store memory addresses of other variables. Pointers provide a
powerful way to directly manipulate memory, but they also introduce potential problems such as
dangling pointers, wild pointers, and null pointer assignments. Understanding pointers and
reference variables is essential for managing dynamic memory, working with arrays, and handling
complex data structures such as objects.
1. Void Pointer
A void pointer is a special type of pointer that can point to any data type. It is a generic pointer, and
its type is not defined when it is declared. To dereference a void pointer, it must first be typecast
into another pointer type.
Code Example:
#include <iostream>
using namespace std;
int main() {
int x = 10;
float y = 5.5;
ptr = &y;
print(ptr, 'f'); // Prints the float
return 0;
}
Explanation:
• void* is used as a pointer to any data type.
• The type of the data is identified by the type parameter, and then the pointer is typecasted
before dereferencing.
2. Pointer Arithmetic
Pointer arithmetic allows you to perform operations on pointers, such as incrementing or
decrementing them, and accessing memory locations at a specific offset.
Code Example:
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40};
int* ptr = arr;
return 0;
}
Explanation:
• Pointer arithmetic is used to navigate through an array. ptr++ increments the pointer,
moving to the next array element.
3. Pointer to Pointer
A pointer to a pointer is a pointer that stores the address of another pointer. This is used when
dealing with dynamic memory allocation or multi-level data structures.
Code Example:
#include <iostream>
using namespace std;
int main() {
int num = 10;
int* ptr = # // Pointer to integer
int** ptr2 = &ptr; // Pointer to pointer
return 0;
}
Explanation:
• ptr is a pointer to an integer, and ptr2 is a pointer to a pointer to an integer.
• **ptr2 accesses the value of num by dereferencing twice.
Wild Pointer
A wild pointer is an uninitialized pointer that points to some arbitrary memory location.
int* createArray() {
int* arr = new int[5]; // Dynamically allocated memory
return arr;
}
int main() {
int* ptr = createArray();
delete[] ptr; // Deallocating memory
cout << *ptr << endl; // Dereferencing a dangling pointer - Undefined
behavior
return 0;
}
Explanation:
• ptr becomes a dangling pointer after memory is deallocated using delete[].
• wildPtr is uninitialized, leading to undefined behavior when dereferenced.
Code Example:
#include <iostream>
using namespace std;
class MyClass {
private:
int* ptr;
public:
MyClass(int val) {
ptr = new int(val); // Dynamically allocating memory
}
~MyClass() {
delete ptr; // Deallocating memory in the destructor
}
void display() {
cout << "Value: " << *ptr << endl;
}
};
int main() {
MyClass obj(100);
obj.display();
return 0;
}
Explanation:
• MyClass contains a pointer ptr, and memory is dynamically allocated in the constructor.
The memory is freed in the destructor to prevent memory leaks.
6. Pointer to Objects
A pointer to an object is used to point to an instance of a class. This allows for dynamic memory
allocation and can be useful when working with arrays of objects or when passing objects to
functions.
Code Example:
#include <iostream>
using namespace std;
class Box {
public:
int length;
int main() {
Box* ptr = new Box(10); // Dynamically creating a Box object
cout << "Box length: " << ptr->length << endl;
delete ptr; // Deallocating memory
return 0;
}
Explanation:
• ptr is a pointer to an object of class Box, and it points to a dynamically allocated object.
The object is deleted after use.
7. The this Pointer
The this pointer is an implicit pointer available to all non-static member functions of a class. It
points to the object that is currently calling the function.
Code Example:
#include <iostream>
using namespace std;
class Box {
public:
int length;
void display() {
cout << "Length: " << this->length << endl; // Using this pointer
}
};
int main() {
Box box(5);
box.display();
return 0;
}
Explanation:
• The this pointer is used to refer to the current object. It is often used to differentiate
between local variables and member variables.
8. Array of Objects
An array of objects is an array where each element is an instance of a class. This is useful when you
need to store multiple objects of the same class.
Code Example:
#include <iostream>
using namespace std;
class Box {
public:
int length;
void display() {
cout << "Length: " << length << endl;
}
};
int main() {
Box boxes[3] = {Box(5), Box(10), Box(15)}; // Array of objects
return 0;
}
Explanation:
• boxes is an array of Box objects, and the display() function is called for each object in
the array.
int main() {
string str1 = "Hello";
string str2 = "World";
cout << "Length of the string: " << result.length() << endl;
return 0;
}
Explanation:
• The string class handles dynamic memory management for strings automatically. You
can use operators like + to concatenate strings.
class Matrix {
public:
void display(int arr[2][2]) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
};
int main() {
int mat[2][2] = {{1, 2}, {3, 4}};
Matrix obj;
obj.display(mat);
return 0;
}
Explanation:
• The class Matrix has a member function display that takes a 2D array and prints its
elements.
Code Example:
#include <iostream>
using namespace std;
class Box {
public:
int length;
int main() {
Box box(10);
int Box::*ptr = &Box::length; // Pointer to data member
cout << "Length: " << box.*ptr << endl; // Accessing data member through
pointer
return 0;
}
Explanation:
• ptr is a pointer to the length data member of the Box class.
• The .* operator is used to access the data member using the pointer.
Summary Table
Concept Description
Void Pointer A pointer that can point to any data type.
Operations like increment and decrement on pointers to access
Pointer Arithmetic
memory.
Pointer to Pointer A pointer that stores the address of another pointer.
Possible Pointer Problems Dangling pointer, wild pointer, null pointer assignment.
Classes Containing Classes can contain pointers to dynamically allocate and free
Pointers memory.
Pointer to Objects A pointer that points to an instance of a class.
A pointer available in non-static member functions that points to the
This Pointer
object.
Array of Objects An array where each element is an instance of a class.
Standard C++ String Class Class for handling strings with built-in functions for manipulation.
Pointer vs Reference Pointers hold memory addresses; references are aliases for variables.
Multidimensional Arrays Arrays of arrays, processed inside functions or classes.
Pointer to Data Member A pointer that points to a specific data member of a class.
UNIT 3
2. Modes of File
Here are the common file opening modes:
• ios::in: Open for input (reading).
• ios::out: Open for output (writing).
• ios::app: Open for appending (writing at the end of the file).
• ios::binary: Open in binary mode (default is text mode).
• ios::trunc: Open and truncate the file to zero length (default when opening for writing).
int main() {
// Writing to a file
ofstream outFile("example.txt", ios::out);
if (!outFile) {
cout << "Error opening file for writing!" << endl;
return 1;
}
outFile << "Hello, File Handling in C++!" << endl;
outFile.close(); // Close the file after writing
return 0;
}
Explanation:
• ofstream is used for writing to files.
• ifstream is used for reading from files.
• Files are opened in ios::out and ios::in modes, respectively.
• After operations, files are closed with the close() function.
int main() {
// Open a binary file for random access
fstream file("example.bin", ios::in | ios::out | ios::binary);
if (!file) {
cout << "Error opening file!" << endl;
return 1;
}
Explanation:
• seekg(): Moves the get pointer (reading position).
• seekp(): Moves the put pointer (writing position).
• File is opened in binary mode (ios::binary) for random access.
struct Employee {
int id;
char name[20];
};
int main() {
// Writing to binary file
Employee emp = {101, "John Doe"};
ofstream outFile("employee.dat", ios::binary);
if (!outFile) {
cout << "Error opening file!" << endl;
return 1;
}
outFile.write(reinterpret_cast<char*>(&emp), sizeof(emp));
outFile.close();
return 0;
}
Explanation:
• reinterpret_cast<char*> is used to convert the address of a structure into a pointer
to a char for binary writing and reading.
• The file is opened in binary mode using ios::binary.
class Student {
private:
int rollNo;
string name;
public:
void setData(int r, const string& n) {
rollNo = r;
name = n;
}
void display() {
cout << "Roll No: " << rollNo << ", Name: " << name << endl;
}
void writeToFile() {
ofstream outFile("student.txt", ios::out);
if (outFile) {
outFile << rollNo << endl;
outFile << name << endl;
}
}
void readFromFile() {
ifstream inFile("student.txt", ios::in);
if (inFile) {
inFile >> rollNo;
inFile.ignore();
getline(inFile, name);
}
}
};
int main() {
Student s1;
s1.setData(101, "Alice");
s1.writeToFile();
Student s2;
s2.readFromFile();
s2.display();
return 0;
}
Explanation:
• The Student class has member functions to write to and read from a file.
• The writeToFile method writes the student's data to a file, while readFromFile
reads data from the file into the object's attributes.
7. Structures and File Operations
You can also use structures to perform file operations. A structure allows you to group different
types of data and is useful when working with records.
struct Product {
int id;
char name[20];
};
int main() {
Product prod = {101, "Laptop"};
return 0;
}
Explanation:
• Product structure is used to store data.
• reinterpret_cast<char*> is used for binary file operations.
void writeData() {
outFile << "Data written using constructor and destructor!" << endl;
}
};
int main() { FileManager fileManager; fileManager.writeData(); return 0; }
**Explanation:**
- The `FileManager` class has a constructor to open the file for writing and a
destructor to close it automatically when the object is destroyed.
Summary of Concepts:
Concept Description
File Opening & Closing Use open() and close() to manage files.
File Modes Define file access mode: read, write, append, binary.
Sequential vs Random Sequential: Data is processed in order; Random: Data accessed at any
Access position.
Binary File Operations Reading/writing data in binary format using ios::binary .
Classes & File Handling Encapsulate file operations in classes for better structure.
Structures & File Use structures to manage record-like data when performing file
Operations operations.
Constructors &
Automate initialization and cleanup with constructors and destructo
Destructors
UNIT 4
class Complex {
public:
int real, imag;
void display() {
cout << "Complex Number: " << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(4, 5);
Complex c2 = -c1; // Using overloaded unary operator
c2.display(); // Output: Complex Number: -4 + -5i
return 0;
}
Explanation:
• The operator-() function overloads the negation (-) operator for the Complex class. It
negates both the real and imaginary parts of the complex number.
class Complex {
public:
int real, imag;
void display() {
cout << "Complex Number: " << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(4, 5), c2(1, 2);
Complex c3 = c1 + c2; // Using overloaded binary operator
c3.display(); // Output: Complex Number: 5 + 7i
return 0;
}
Explanation:
• The operator+() function overloads the addition (+) operator for the Complex class. It
adds the real and imaginary parts of two Complex objects.
Explicit Conversion:
Explicit conversion is done by defining a constructor or conversion operator in the class.
class Complex {
public:
int real, imag;
// Constructor to initialize Complex from an int
Complex(int r) : real(r), imag(0) {}
void display() {
cout << "Complex Number: " << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1 = 5; // Implicit conversion from int to Complex (calls
Complex(int))
c1.display(); // Output: Complex Number: 5 + 0i
return 0;
}
Explanation:
• The implicit conversion is achieved by the constructor Complex(int r), which allows
an int to be directly assigned to a Complex object.
• The explicit conversion is done by passing two arguments to the Complex constructor.
class Complex {
public:
int real, imag;
void display() {
cout << "Complex Number: " << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c(5, 7);
int x = c; // Calls the conversion operator
cout << "Real part as int: " << x << endl; // Output: Real part as int: 5
return 0;
}
Explanation:
• The operator int() function is a conversion operator that converts a Complex
object to an int by returning the real part.
Inheritance in C++
Inheritance allows one class (the derived class) to inherit the properties and methods of another
class (the base class). Inheritance promotes code reuse and creates a hierarchy of classes.
Types of Inheritance:
• Single Inheritance: A class inherits from only one base class.
• Multilevel Inheritance: A class inherits from a class that is already derived from another
class.
• Multiple Inheritance: A class inherits from more than one base class.
• Hierarchical Inheritance: Multiple classes inherit from a single base class.
Modes of Inheritance:
• Private: The members of the base class are inherited as private in the derived class.
• Protected: The members of the base class are inherited as protected in the derived class.
• Public: The members of the base class are inherited as public in the derived class.
class Base {
public:
void displayBase() {
cout << "This is the base class" << endl;
}
};
int main() {
Derived obj;
obj.displayBase(); // Access base class method
obj.displayDerived(); // Access derived class method
return 0;
}
Explanation:
• The derived class Derived inherits from the base class Base using public inheritance.
This allows the derived class to access the public methods of the base class.
Order of Execution of Constructors and Destructors
• The constructor of the base class is called before the constructor of the derived class.
• The destructor of the derived class is called before the destructor of the base class.
class Base {
public:
Base() {
cout << "Base class constructor" << endl;
}
~Base() {
cout << "Base class destructor" << endl;
}
};
~Derived() {
cout << "Derived class destructor" << endl;
}
};
int main() {
Derived obj;
return 0;
}
Output:
Base class constructor
Derived class constructor
Derived class destructor
Base class destructor
Explanation:
• The Base class constructor is called first, followed by the Derived class constructor.
• When the object is destroyed, the Derived class destructor is called first, followed by the
Base class destructor.
int main() {
Final obj;
obj.display(); // Output:
---
Concept Description
Operator Allows defining custom behavior for operators (+, -, etc.) in user-defined
Overloading types.
Unary Operator Operates on one operand (e.g., negation operator - ).
Binary Operator Operates on two operands (e.g., addition operator + ).
Converting between basic types and class types using constructors and
Type Conversion
operators.
A mechanism to derive a new class from an existing class, supporting code
Inheritance
reuse.
Types of Inheritance Single, multilevel, multiple, and hierarchical inheritance.
Private, protected, and public inheritance control access to inherited
Modes of Inheritance
members.
Virtual Base Class Resolves ambiguities in diamond inheritance.
UNIT 5
int main() {
int *ptr = new int; // dynamically allocating memory for an integer
*ptr = 10; // assigning a value to the allocated memory
cout << "Value: " << *ptr << endl; // Output: Value: 10
Explanation:
• new int allocates memory for an integer on the heap, and delete ptr frees the
allocated memory.
• Using new[] and delete[] can be used for arrays.
int main() {
int n = 5;
int *arr = new int[n]; // dynamically allocating an array of 5 integers
class Base {
public:
Base() {
cout << "Base class constructor" << endl;
}
~Derived() {
cout << "Derived class destructor" << endl;
}
};
int main() {
Base* ptr = new Derived(); // Base pointer pointing to derived object
delete ptr; // Calls the destructor of Derived class followed by Base class
destructor
return 0;
}
Output:
Base class constructor
Derived class constructor
Derived class destructor
Base class destructor
Explanation:
• The destructor in the base class is declared as virtual, so when we delete the Derived
object using a Base pointer, both the base and derived destructors are called.
4. Virtual Functions
A virtual function is a member function in a base class that you expect to be overridden in derived
classes. When a function is declared as virtual, C++ ensures that the correct function is called for an
object, regardless of the type of the pointer or reference.
class Base {
public:
virtual void display() { // Virtual function
cout << "Base class display function" << endl;
}
};
int main() {
Base* ptr;
Derived obj;
ptr = &obj;
ptr->display(); // Output: Derived class display function (Run-time
polymorphism)
return 0;
}
Explanation:
• The display() function in Base is virtual, and the correct display() function is
called based on the actual object type (Derived), even though the pointer is of type
Base*.
5. Dynamic Constructors
Dynamic constructors are constructors that allocate memory dynamically for the data members of
the class. This can be done inside the constructor using the new operator.
class MyClass {
int* ptr;
public:
MyClass(int size) {
ptr = new int[size]; // Dynamically allocating memory for the array
}
~MyClass() {
delete[] ptr; // Deallocating the memory
}
void display() {
cout << "Displaying data..." << endl;
}
};
int main() {
MyClass obj(10); // Dynamically allocating memory in the constructor
obj.display();
return 0;
}
class Abstract {
public:
virtual void show() = 0; // Pure virtual function (abstract)
};
int main() {
// Abstract obj; // Error: Cannot instantiate abstract class
Concrete obj;
obj.show(); // Output: Concrete class implementation
return 0;
}
Explanation:
• Abstract is an abstract class because it has a pure virtual function show().
• Concrete is a concrete class because it provides an implementation for the show()
function.
7. Pure Virtual Functions
A pure virtual function is a function that has no definition in the base class and is required to be
overridden in derived classes. It is declared by assigning = 0 to the function prototype.
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;
}
Explanation:
• The draw() function is a pure virtual function in the Shape class, making Shape an
abstract class.
• Derived classes Circle and Square provide implementations for the draw() function.
int main() {
int* ptr = new int(10); // Dynamically allocating memory
// Forgot to deallocate memory, causing a memory leak
return 0;
}
Explanation:
• In this case, memory is allocated with new but never freed, causing a memory leak.
int main() {
try {
int* ptr = new int[1000000000000]; // Trying to allocate too much
memory
} catch (bad_alloc& e) {
cout << "Memory allocation failed: " << e.what() << endl;
}
return 0;
}
Explanation:
• If the system cannot allocate the required memory, a std::bad_alloc exception is
thrown.
Concept Description
Dynamic Memory
Memory is allocated and deallocated using new and delete .
Allocation
Virtual Destructors Ensures correct destructor calls in inheritance hierarchies.
Compile-time
Resolved at compile time (function overloading, operator overloading).
Polymorphism
Run-time Polymorphism Resolved at runtime using virtual functions and inheritance.
Functions with no implementation in base class, forcing derived classes
Pure Virtual Functions
to provide one.
Memory Leak Occurs when dynamically allocated memory is not freed.
UNIT 1
int main() {
try {
int result = divide(10, 0); // This will throw an exception
cout << "Result: " << result << endl;
} catch (const char* msg) { // Catching the exception
cout << "Error: " << msg << endl; // Output: Error: Division by zero is
not allowed!
}
return 0;
}
Explanation:
• The divide function checks if b is zero and throws an exception using throw.
• The catch block catches the exception and displays an error message.
3. Throwing Mechanism
The throw keyword is used to throw an exception in C++. It is typically followed by an object that
represents the error. The exception can be of any type, such as built-in types, custom classes, or
pointers.
void test() {
throw 10; // Throwing an integer exception
}
int main() {
try {
test(); // Function that throws an exception
} catch (int e) { // Catching integer exception
cout << "Caught exception: " << e << endl; // Output: Caught exception:
10
}
return 0;
}
Explanation:
• The throw 10; statement throws an integer exception, which is caught by the catch
block.
4. Catching Mechanism
The catch block is used to catch exceptions thrown by a try block. It follows the try block and
can catch exceptions of different types.
void test(int x) {
if (x == 0)
throw "Zero is not allowed"; // Throwing string exception
else
throw 5; // Throwing integer exception
}
int main() {
try {
test(0); // This will throw a string exception
} catch (const char* msg) {
cout << "Caught exception: " << msg << endl; // Output: Caught
exception: Zero is not allowed
}
try {
test(1); // This will throw an integer exception
} catch (int e) {
cout << "Caught exception: " << e << endl; // Output: Caught exception:
5
}
return 0;
}
Explanation:
• The catch block can catch exceptions of specific types (such as strings and integers).
• Different catch blocks can handle different exception types.
5. Rethrowing an Exception
Sometimes, you may want to catch an exception and then throw it again for further processing by
another handler or to log the error.
void test() {
try {
throw 10; // Throwing an integer exception
} catch (int e) {
cout << "Caught exception: " << e << endl;
throw; // Rethrowing the same exception
}
}
int main() {
try {
test(); // Calls the function which will rethrow the exception
} catch (int e) {
cout << "Rethrown exception caught in main: " << e << endl; // Output:
Rethrown exception caught in main: 10
}
return 0;
}
Explanation:
• The exception is caught inside the test function and then rethrown using throw;.
• The main function catches the rethrown exception.
int main() {
cout << add(5, 10) << endl; // Output: 15
cout << add(3.5, 2.5) << endl; // Output: 6.0
return 0;
}
Explanation:
• template <typename T> defines a function template that works with any data type T.
• The add function can be used for different types, such as integers or doubles.
int main() {
Box<int> intBox(10);
Box<double> doubleBox(3.14);
Explanation:
• Box<T> is a class template, and it can be instantiated with different types, like int and
double.
int main() {
Derived<int> obj(20);
obj.display(); // Output: Derived value: 20
return 0;
}
Explanation:
• The Derived class inherits from the Base class template, and it can access and display the
value member.
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
Explanation:
• vector<int> is a container that stores integers.
• The push_back() function adds an element at the end of the vector.
Example: STL List
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> lst = {10, 20, 30};
}
return 0;
**Explanation:**
- `list<int>` is a container that stores integers in a doubly linked list.
- `push_front()` and `push_back()` allow insertion at the beginning and end of
the list, respectively.
---
Topic Description
Exception
Mechanism to handle runtime errors using try , throw , and catch blocks.
Handling
Function
Allows the creation of functions that can operate with any data type.
Templates
Class Templates Allows the creation of classes that can operate with any data type.
Predefined classes like vector , list , and map that store data in different
STL Containers
ways.
Functions that perform operations like sorting, searching, and modifying data
STL Algorithms
in containers.
Objects used to iterate through containers,
STL Iterators like begin() and end() methods.