C++ Programming Tutorial
C vs C++
C and C++ are both powerful programming languages, but they differ in key ways:
- C: Procedural programming language that focuses on functions and procedures.
- C++: Object-oriented programming language that supports classes and objects, offering more abstraction and modularity.
C++ History
C++ was created by Bjarne Stroustrup in the early 1980s at Bell Labs. It is an extension of the C programming language, designed to add object-oriented features such as classes and objects while maintaining C’s efficiency and power. C++ became widely popular for developing system software, games, applications, and even real-time systems due to its flexibility and speed.
C++ Features
C++ offers numerous features:
- Object-Oriented Programming (OOP): Supports classes, objects, inheritance, polymorphism, and encapsulation.
- STL (Standard Template Library): Includes pre-written templates for common data structures like vectors, lists, and maps.
- Memory Management: Provides dynamic memory allocation and deallocation with operators
newanddelete. - Low-Level Manipulation: Allows for direct memory access using pointers, similar to C.
- Function Overloading: Supports the creation of multiple functions with the same name but different signatures.
C++ Installation
To get started with C++, you'll need a C++ compiler. Some of the most popular compilers are:
- GCC: The GNU Compiler Collection, available on Linux, Windows (via MinGW), and macOS.
- MSVC: Microsoft's Visual C++ compiler, part of the Visual Studio IDE.
- Clang: A compiler used on macOS and Linux, known for its speed and diagnostics.
First C++ Program
Here’s a simple C++ program that prints “Hello, World!” to the console:
#include <iostream>
using namespace std;
int main() {
cout << "Hello, World!" << endl;
return 0;
}
This program demonstrates the basic structure of a C++ program, including the use of the iostream library, the main() function, and the cout function to print to the console.
C++ cout, cin, endl
- cout: Used to print output to the console.
- cin: Used to get user input from the console.
- endl: Used to insert a new line in the output stream, similar to the newline character \n.
#include <iostream>
using namespace std;
int main() {
int age;
cout << "Enter your age: ";
cin >> age;
cout << "Your age is: " << age << endl;
return 0;
}
In this example, the program prompts the user for their age and prints it out using cin and cout.
C++ Variables
Variables in C++ are used to store data values. You need to specify the type of the variable at the time of declaration. Common variable types include int, float, char, and bool.
int age = 25; float height = 5.9; char grade = 'A'; bool isStudent = true;
C++ Data Types
C++ supports several data types that can be used to declare variables:
- Primitive Types:
int,float,double,char,bool - Derived Types: Arrays, Pointers, References
- User-Defined Types: Classes, Structures, Unions, Enums
C++ Keywords
C++ has several reserved keywords that have special meanings. These include:
- int, float, double - Used to declare variables of specific types.
- if, else, switch - Control flow keywords for conditional statements.
- class, public, private, protected - Used for object-oriented programming features.
- new, delete - For dynamic memory allocation and deallocation.
C++ Operators
Operators are used to perform operations on variables and values. C++ includes a variety of operators:
- Arithmetic Operators: +, -, *, /, %
- Relational Operators: ==, !=, >, <, >=, <=
- Logical Operators: &&, ||, !
- Assignment Operators: =, +=, -=, *=, /=
- Bitwise Operators: &, |, ^, ~, <<, >>
C++ Identifiers
Identifiers are names given to various program elements such as variables, functions, and classes. They must:
- Begin with a letter or an underscore (_).
- Contain only letters, numbers, and underscores.
- Not be a C++ reserved keyword.
C++ Expression
An expression is a combination of variables, constants, operators, and functions that are evaluated to produce a value. For example:
int result = 5 + 10 * 2;
This expression evaluates to 25, with the multiplication operation being performed first due to operator precedence.
C++ Control Statement
C++ if-else
The `if-else` statement is used to execute a block of code based on a condition. If the condition is true, one block of code runs; otherwise, another block runs.
int num = 10;
if (num > 0) {
cout << "Positive number" << endl;
} else {
cout << "Negative number" << endl;
}
In this example, the program checks if the number is positive or negative using the `if-else` statement.
C++ switch
The `switch` statement allows you to test a variable against a series of values. It is an alternative to multiple `if-else` conditions.
int day = 3;
switch (day) {
case 1:
cout << "Monday" << endl;
break;
case 2:
cout << "Tuesday" << endl;
break;
case 3:
cout << "Wednesday" << endl;
break;
default:
cout << "Invalid day" << endl;
}
Here, the program uses a `switch` to print the name of the day based on the value of the variable `day`.
C++ For Loop
The `for` loop is used to execute a block of code a specific number of times. It is commonly used when the number of iterations is known in advance.
for (int i = 0; i < 5; i++) {
cout << "Iteration " << i << endl;
}
In this example, the loop runs 5 times, printing the iteration number each time.
C++ While Loop
The `while` loop repeatedly executes a block of code as long as the specified condition is true.
int i = 0;
while (i < 5) {
cout << "Iteration " << i << endl;
i++;
}
In this example, the `while` loop prints the iteration number, and the loop continues as long as `i` is less than 5.
C++ Do-While Loop
The `do-while` loop is similar to the `while` loop, but it guarantees that the block of code will execute at least once before checking the condition.
int i = 0;
do {
cout << "Iteration " << i << endl;
i++;
} while (i < 5);
The `do-while` loop executes the code once and then checks the condition (`i < 5`). The loop continues until the condition becomes false.
C++ Break Statement
The `break` statement is used to exit from a loop or `switch` statement prematurely. It can be used to terminate a loop based on a condition.
for (int i = 0; i < 10; i++) {
if (i == 5) {
break;
}
cout << "Iteration " << i << endl;
}
In this example, the loop will terminate when `i` equals 5 due to the `break` statement.
C++ Continue Statement
The `continue` statement is used to skip the current iteration of a loop and proceed to the next iteration.
for (int i = 0; i < 5; i++) {
if (i == 3) {
continue;
}
cout << "Iteration " << i << endl;
}
In this example, when `i` equals 3, the `continue` statement will skip that iteration, and the loop will proceed to the next iteration.
C++ Comments
Comments are used to explain the code and make it more readable. C++ supports both single-line and multi-line comments:
- Single-line comment:
// This is a comment - Multi-line comment:
/* This is a multi-line comment */
// This is a single-line comment /* This is a multi-line comment */
C++ Functions
C++ Functions
Functions in C++ are used to group code into reusable blocks that can be called when needed. A function is defined by its return type, name, and parameters.
// Function declaration
int add(int a, int b);
// Function definition
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(5, 3);
cout << "Sum: " << result << endl;
return 0;
}
In this example, the function add is declared and defined to return the sum of two integers. The function is then called in main to calculate and print the result.
Call by Value & Reference
In C++, functions can be called either by value or by reference:
- Call by Value: The actual value is passed, and the function works with a copy of the data.
- Call by Reference: A reference to the actual data is passed, so any changes to the parameter affect the actual argument.
Call by Value
void addByValue(int x) {
x = x + 5; // Modifying the local copy
}
int main() {
int a = 10;
addByValue(a); // Passes a copy
cout << "Value of a: " << a << endl; // Prints 10, as a is not modified
return 0;
}
Call by Reference
void addByReference(int &x) {
x = x + 5; // Modifies the original value
}
int main() {
int a = 10;
addByReference(a); // Passes reference
cout << "Value of a: " << a << endl; // Prints 15, as a is modified
return 0;
}
In the first example (call by value), the value of a remains unchanged. In the second example (call by reference), the value of a is modified within the function.
C++ Recursion
Recursion is a technique where a function calls itself to solve a smaller instance of the problem. It typically requires a base case to prevent infinite recursion.
// Function to calculate factorial using recursion
int factorial(int n) {
if (n == 0) {
return 1; // Base case
}
return n * factorial(n - 1); // Recursive case
}
int main() {
int result = factorial(5);
cout << "Factorial: " << result << endl; // Prints 120
return 0;
}
In this example, the factorial function calls itself to calculate the factorial of a number. The base case is when n equals 0, where the recursion stops.
C++ Storage Classes
Storage classes in C++ define the scope, visibility, and lifetime of variables. The major storage classes in C++ are:
- auto: Default storage class for local variables. The lifetime is limited to the scope of the function.
- register: Used for variables that are frequently accessed, suggesting they should be stored in a CPU register.
- static: Used to keep the value of a variable between function calls.
- extern: Used to declare variables that are defined outside the current function or file.
auto Example
void function() {
auto x = 10; // auto infers type as int
cout << "x = " << x << endl;
}
static Example
void function() {
static int counter = 0; // Static variable persists between function calls
counter++;
cout << "Counter: " << counter << endl;
}
int main() {
function(); // Counter: 1
function(); // Counter: 2
return 0;
}
In the static example, the variable counter retains its value between function calls because it is declared as static.
C++ Arrays
An array in C++ is a collection of elements of the same type placed in contiguous memory locations. The array is used to store multiple values in a single variable, instead of declaring separate variables for each value.
// Declare an array of 5 integers
int arr[5] = {1, 2, 3, 4, 5};
// Accessing elements of the array
cout << "First element: " << arr[0] << endl; // Output: 1
cout << "Last element: " << arr[4] << endl; // Output: 5
In this example, an array of 5 integers is declared and initialized. The elements of the array can be accessed using the index starting from 0.
C++ Array to Function
In C++, we can pass an array to a function. When passing an array to a function, we do not pass the array as a whole but instead pass a pointer to the first element of the array. Thus, changes made to the array inside the function will affect the original array.
// Function to display elements of an array
void displayArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
int main() {
int arr[5] = {10, 20, 30, 40, 50};
displayArray(arr, 5); // Passing array to function
return 0;
}
In this example, the `displayArray` function takes an array and its size as parameters and displays the array elements.
Multidimensional Arrays
A multidimensional array is an array of arrays. The most common example is a 2D array, which can be visualized as a table with rows and columns. In C++, we can declare a 2D array and access its elements using row and column indices.
// Declare a 2D array (3 rows, 3 columns)
int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
// Accessing elements
cout << "Element at row 1, column 2: " << arr[0][1] << endl; // Output: 2
In this example, a 2D array is declared and initialized. The elements can be accessed using two indices: the row index and the column index.
Passing Multidimensional Array to a Function
// Function to display a 2D array
void display2DArray(int arr[][3], int rows) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
int main() {
int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
display2DArray(arr, 3); // Passing 2D array to function
return 0;
}
In this example, a 2D array is passed to the `display2DArray` function. The function loops through both rows and columns to display the elements.
C++ Pointers
A pointer in C++ is a variable that stores the memory address of another variable. Pointers are used to dynamically allocate memory, work with arrays, and interact with functions more efficiently.
// Declaring and using a pointer int num = 10; int* ptr = # // Pointer ptr stores the address of num cout << "Value of num: " << *ptr << endl; // Dereferencing the pointer to get the value cout << "Address of num: " << ptr << endl; // Address stored in ptr
In this example, `ptr` is a pointer that stores the address of the variable `num`. We use the dereference operator (`*`) to get the value stored at that memory address.
sizeof() operator in C++
The `sizeof()` operator in C++ is used to determine the size, in bytes, of a data type or a variable. It is often used when working with pointers, arrays, and dynamic memory allocation.
// Using sizeof to get the size of a variable int num = 10; cout << "Size of num: " << sizeof(num) << " bytes" << endl; // Output the size of num // Using sizeof with pointers int* ptr = # cout << "Size of pointer: " << sizeof(ptr) << " bytes" << endl; // Output size of pointer
The `sizeof()` operator returns the size of a variable or pointer. In the above example, we calculate the size of an integer and a pointer.
C++ Array of Pointers
An array of pointers in C++ is an array where each element is a pointer that points to a memory location (usually pointing to an array or a data element).
// Array of pointers int* arr[3]; // Array of 3 integer pointers int num1 = 10, num2 = 20, num3 = 30; arr[0] = &num1; arr[1] = &num2; arr[2] = &num3; cout << "First value: " << *arr[0] << endl; // Output: 10 cout << "Second value: " << *arr[1] << endl; // Output: 20 cout << "Third value: " << *arr[2] << endl; // Output: 30
Here, `arr` is an array of pointers that point to the memory addresses of the variables `num1`, `num2`, and `num3`. By dereferencing each pointer, we can access the values stored at those memory locations.
C++ Void Pointer
A void pointer in C++ is a special type of pointer that can point to any data type. Since a void pointer does not have a data type, it cannot be dereferenced directly without type casting.
// Void pointer example
void* ptr;
int num = 10;
ptr = # // Assign address of num to void pointer
cout << "Value of num: " << *(static_cast<int*>(ptr)) << endl; // Type casting to dereference
In this example, `ptr` is a void pointer that points to the address of `num`. Before dereferencing the void pointer, we need to cast it to the appropriate type.
C++ References
A reference in C++ is an alias for an existing variable. Once a reference is initialized to a variable, it cannot be changed to refer to another variable.
// Reference example
int num = 10;
int& ref = num; // ref is a reference to num
cout << "Value of num: " << ref << endl; // Output: 10
ref = 20; // Changes num to 20
cout << "Updated value of num: " << num << endl; // Output: 20
A reference acts as a pointer but provides a simpler syntax. It can be used to modify the value of a variable directly.
Reference vs Pointer
A reference is an alias for a variable, while a pointer stores the memory address of a variable. A reference must always be initialized at the time of declaration, and it cannot be null, whereas a pointer can be reassigned to different memory addresses and can be null.
Function Pointer in C++
A function pointer in C++ is a pointer that points to a function instead of a variable. This allows for dynamic function calls, where the function to be called is determined at runtime.
// Function pointer example
void greet() {
cout << "Hello, World!" << endl;
}
int main() {
void (*funcPtr)() = &greet; // Declare a function pointer
funcPtr(); // Calling the function through pointer
return 0;
}
In this example, `funcPtr` is a pointer to the `greet` function. We use the function pointer to call `greet()` indirectly.
C++ Memory Management
C++ provides two operators for dynamic memory management: new and delete. The new operator allocates memory for a variable or array dynamically, while delete frees up the allocated memory. Memory management is essential in C++ to prevent memory leaks and ensure efficient use of system resources.
// Example of using 'new' and 'delete' in C++
int* ptr = new int; // Dynamically allocate memory for an integer
*ptr = 10; // Assign value to the allocated memory
cout << "Value: " << *ptr << endl; // Output: 10
delete ptr; // Free the dynamically allocated memory
In the above code, we use new to allocate memory for an integer, assign a value to it, and later deallocate the memory using delete.
malloc() vs new in C++
The malloc() function in C is used to allocate memory dynamically, while new in C++ performs the same task but provides better memory handling and type safety. new also initializes the memory, whereas malloc() does not. Additionally, new returns a pointer of the correct type, while malloc() returns a void* pointer that needs to be type-cast.
// Using malloc() in C
#include <cstdlib> // For malloc()
int* ptr = (int*)malloc(sizeof(int)); // Allocate memory for an integer
*ptr = 20; // Assign value
cout << "Value from malloc: " << *ptr << endl; // Output: 20
free(ptr); // Free the memory allocated by malloc()
// Using new in C++
int* ptrNew = new int; // Allocate memory using new
*ptrNew = 20; // Assign value
cout << "Value from new: " << *ptrNew << endl; // Output: 20
delete ptrNew; // Free the memory allocated by new
In the example above, we show how both malloc() and new are used for dynamic memory allocation. While malloc() requires type casting, new handles type safety automatically.
free vs delete in C++
In C++, delete is used to deallocate memory that was allocated using new. The free() function in C is used to deallocate memory allocated by malloc() in C. However, delete also calls the destructor for objects, whereas free() does not. This makes delete safer and more appropriate for C++ as it handles object destruction as well.
// Using free() in C
#include <cstdlib> // For free()
int* ptrMalloc = (int*)malloc(sizeof(int)); // Using malloc
*ptrMalloc = 30;
cout << "Value from malloc: " << *ptrMalloc << endl; // Output: 30
free(ptrMalloc); // Deallocate memory
// Using delete in C++
int* ptrNewDelete = new int; // Using new
*ptrNewDelete = 30;
cout << "Value from new: " << *ptrNewDelete << endl; // Output: 30
delete ptrNewDelete; // Deallocate memory
In this example, we compare how free() and delete are used to deallocate memory. While free() is used for memory allocated by malloc(), delete is used for memory allocated by new. Using delete ensures proper cleanup, including calling object destructors.
C++ Object Class
In C++, a class is a blueprint for creating objects. An object is an instance of a class. A class defines the properties (data members) and behaviors (methods) that the object will have. Here's a simple example of a class and object in C++.
// C++ Class Example
class MyClass {
public:
int number; // Data member
void display() { // Member function
cout << "Number: " << number << endl;
}
};
int main() {
MyClass obj; // Object creation
obj.number = 10;
obj.display(); // Output: Number: 10
return 0;
}
C++ Constructor
A constructor is a special member function that is called automatically when an object of a class is created. It is used to initialize objects.
// C++ Constructor Example
class MyClass {
public:
int number;
// Constructor
MyClass(int num) {
number = num;
}
void display() {
cout << "Number: " << number << endl;
}
};
int main() {
MyClass obj(100); // Constructor is called
obj.display(); // Output: Number: 100
return 0;
}
C++ Copy Constructor
A copy constructor is used to create a new object as a copy of an existing object. It's automatically invoked when an object is passed by value or returned by value.
// C++ Copy Constructor Example
class MyClass {
public:
int number;
MyClass(int num) {
number = num;
}
// Copy Constructor
MyClass(const MyClass &obj) {
number = obj.number;
}
void display() {
cout << "Number: " << number << endl;
}
};
int main() {
MyClass obj1(10);
MyClass obj2 = obj1; // Copy constructor is called
obj2.display(); // Output: Number: 10
return 0;
}
C++ Destructor
A destructor is a special member function that is called when an object goes out of scope or is explicitly deleted. It is used to release resources.
// C++ Destructor Example
class MyClass {
public:
int number;
MyClass(int num) {
number = num;
cout << "Object created with number: " << number << endl;
}
// Destructor
~MyClass() {
cout << "Object with number " << number << " is destroyed" << endl;
}
};
int main() {
MyClass obj(100); // Destructor will be called when object goes out of scope
return 0; // Output: Object created with number: 100, Object with number 100 is destroyed
}
C++ this Pointer
The this pointer is a special pointer that points to the current object of the class. It is implicitly passed to all non-static member functions.
// C++ this Pointer Example
class MyClass {
public:
int number;
void setNumber(int number) {
this->number = number; // Using 'this' pointer
}
void display() {
cout << "Number: " << number << endl;
}
};
int main() {
MyClass obj;
obj.setNumber(10); // Using 'this' to set the value
obj.display(); // Output: Number: 10
return 0;
}
C++ static
A static variable or function is shared across all objects of the class. It is not tied to any specific object and is initialized only once.
// C++ static variable example
class MyClass {
public:
static int count; // Static variable
MyClass() {
count++;
}
static void display() { // Static member function
cout << "Object count: " << count << endl;
}
};
int MyClass::count = 0; // Initialize static variable
int main() {
MyClass obj1, obj2;
MyClass::display(); // Output: Object count: 2
return 0;
}
C++ Structs
A struct in C++ is similar to a class, but by default, its members are public. Structs are typically used to represent data structures.
// C++ Struct Example
struct MyStruct {
int number;
void display() {
cout << "Number: " << number << endl;
}
};
int main() {
MyStruct obj;
obj.number = 10;
obj.display(); // Output: Number: 10
return 0;
}
C++ Enumeration
An enum in C++ defines a set of named integer constants. It improves code readability by giving names to integral values.
// C++ Enum Example
enum Color { Red, Green, Blue };
int main() {
Color color = Red;
cout << "Color: " << color << endl; // Output: Color: 0
return 0;
}
C++ Friend Function
A friend function can access private and protected members of a class. It is not a member function but has access to the class's private data.
// C++ Friend Function Example
class MyClass {
private:
int number;
public:
MyClass(int num) : number(num) {}
// Friend function
friend void display(MyClass obj);
};
void display(MyClass obj) {
cout << "Number: " << obj.number << endl;
}
int main() {
MyClass obj(100);
display(obj); // Output: Number: 100
return 0;
}
C++ Math Functions
C++ provides a library cmath that includes several mathematical functions such as sqrt(), pow(), sin(), and cos().
// C++ Math Functions Example
#include <cmath>
#include <iostream>
int main() {
double num = 16;
cout << "Square root: " << sqrt(num) << endl; // Output: 4
double base = 2, exponent = 3;
cout << "Power: " << pow(base, exponent) << endl; // Output: 8
return 0;
}
C++ Inheritance
In C++, inheritance is a mechanism that allows a class (derived class) to inherit properties and behaviors (methods) from another class (base class). It promotes code reuse and helps create a hierarchical relationship between classes.
The syntax for inheritance is as follows:
class DerivedClass : access_specifier BaseClass { ... }
There are different types of inheritance:
- Single Inheritance
- Multiple Inheritance
- Multilevel Inheritance
- Hierarchical Inheritance
- Hybrid Inheritance
Single Inheritance
Single inheritance is when a class (derived class) inherits properties and behaviors from one base class.
// Single Inheritance Example
#include <iostream>
using namespace std;
class Animal { // Base class
public:
void eat() {
cout << "Eating..." << endl;
}
};
class Dog : public Animal { // Derived class
public:
void bark() {
cout << "Barking..." << endl;
}
};
int main() {
Dog d;
d.eat(); // Inherited method from Animal class
d.bark(); // Method from Dog class
return 0;
}
Multiple Inheritance
Multiple inheritance is when a class inherits from more than one base class. C++ supports multiple inheritance, unlike Java.
// Multiple Inheritance Example
#include <iostream>
using namespace std;
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
class Bird {
public:
void fly() {
cout << "Flying..." << endl;
}
};
class FlyingAnimal : public Animal, public Bird {
public:
void sound() {
cout << "Sound..." << endl;
}
};
int main() {
FlyingAnimal fa;
fa.eat(); // Inherited from Animal class
fa.fly(); // Inherited from Bird class
fa.sound(); // Method from FlyingAnimal class
return 0;
}
Multilevel Inheritance
Multilevel inheritance is when a class is derived from another derived class. This forms a chain of inheritance.
// Multilevel Inheritance Example
#include <iostream>
using namespace std;
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
class Dog : public Animal { // Derived from Animal
public:
void bark() {
cout << "Barking..." << endl;
}
};
class Puppy : public Dog { // Derived from Dog
public:
void play() {
cout << "Playing..." << endl;
}
};
int main() {
Puppy p;
p.eat(); // Inherited from Animal
p.bark(); // Inherited from Dog
p.play(); // Method from Puppy
return 0;
}
Hierarchical Inheritance
In hierarchical inheritance, multiple classes derive from a single base class. All the derived classes can access the base class properties.
// Hierarchical Inheritance Example
#include <iostream>
using namespace std;
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
class Dog : public Animal {
public:
void bark() {
cout << "Barking..." << endl;
}
};
class Cat : public Animal {
public:
void meow() {
cout << "Meowing..." << endl;
}
};
int main() {
Dog d;
Cat c;
d.eat(); // Inherited from Animal
d.bark(); // Dog's method
c.eat(); // Inherited from Animal
c.meow(); // Cat's method
return 0;
}
Hybrid Inheritance
Hybrid inheritance is a combination of more than one type of inheritance. It usually involves a mix of multiple and multilevel inheritance.
// Hybrid Inheritance Example
#include <iostream>
using namespace std;
class Animal {
public:
void eat() {
cout << "Eating..." << endl;
}
};
class Bird {
public:
void fly() {
cout << "Flying..." << endl;
}
};
class Bat : public Animal, public Bird { // Hybrid Inheritance
public:
void sound() {
cout << "Screeching..." << endl;
}
};
int main() {
Bat b;
b.eat(); // Inherited from Animal
b.fly(); // Inherited from Bird
b.sound(); // Method from Bat class
return 0;
}
C++ Aggregation
Aggregation is a type of association where one class contains a reference to another class, but both classes can exist independently. Unlike inheritance, aggregation represents a "has-a" relationship. In aggregation, the child object can exist without the parent object.
Aggregation is often used when a class needs to represent a more complex relationship, but where the life cycle of the contained objects is independent of the container.
// C++ Aggregation Example
#include <iostream>
using namespace std;
class Engine { // Aggregated class
public:
void start() {
cout << "Engine Starting..." << endl;
}
};
class Car { // Class containing the object of Engine
private:
Engine engine; // Aggregation (Car has an Engine)
public:
void startCar() {
engine.start(); // Call Engine's method through Car
cout << "Car is ready!" << endl;
}
};
int main() {
Car car;
car.startCar(); // Output: Engine Starting... Car is ready!
return 0;
}
C++ Polymorphism
Polymorphism in C++ allows methods and objects to take multiple forms. It allows the same method or function to behave differently depending on the context or the type of object. There are two main types of polymorphism in C++:
- Compile-time Polymorphism (Method Overloading and Operator Overloading)
- Runtime Polymorphism (Method Overriding using Virtual Functions)
C++ Overloading
Function overloading allows multiple functions with the same name to be defined, but with different parameter types or a different number of parameters. The compiler determines which function to call based on the number or type of arguments.
// Function Overloading in C++
#include <iostream>
using namespace std;
class Print {
public:
void show(int i) {
cout << "Integer: " << i << endl;
}
void show(double d) {
cout << "Double: " << d << endl;
}
void show(string s) {
cout << "String: " << s << endl;
}
};
int main() {
Print p;
p.show(5); // Calls show(int)
p.show(5.5); // Calls show(double)
p.show("Hello!"); // Calls show(string)
return 0;
}
C++ Overriding
Method overriding occurs when a derived class provides a specific implementation of a method that is already defined in its base class. The method in the base class must be declared as virtual to support runtime polymorphism.
// Method Overriding Example in C++
#include < iostream>
using namespace std;
class Animal {
public:
virtual void sound() { // Virtual function
cout << "Animal sound" << endl;
}
};
class Dog : public Animal {
public:
void sound() override { // Overriding the base class method
cout << "Barking..." << endl;
}
};
int main() {
Animal *animal = new Dog(); // Base class pointer, derived class object
animal->sound(); // Calls the overridden method in Dog class
delete animal;
return 0;
}
C++ Virtual Function
A virtual function in C++ is a function in the base class that is overridden in the derived class. When a function is declared as virtual, the C++ runtime will call the derived class’s version of the function, even if the object is accessed through a base class pointer.
// Virtual Function in C++
#include < iostream>
using namespace std;
class Base {
public:
virtual void display() { // Virtual function in base class
cout << "Base class display" << endl;
}
};
class Derived : public Base {
public:
void display() override { // Overridden function in derived class
cout << "Derived class display" << endl;
}
};
int main() {
Base* b;
Derived d;
b = &d;
// Calls the derived class's display() function because of virtual function
b->display();
return 0;
}
In the above example, even though the pointer b is of type Base*, it calls the display() function from the Derived class because display() is a virtual function. This is an example of runtime polymorphism.
C++ Abstraction
Abstraction is the concept of hiding the complex implementation details and showing only the essential features of the object. In C++, abstraction is achieved using abstract classes and interfaces.
C++ Abstract Class
An abstract class in C++ is a class that cannot be instantiated directly and must have at least one pure virtual function. These pure virtual functions are meant to be overridden by derived classes.
// Abstract Class in C++
#include < iostream>
using namespace std;
// Abstract class
class Shape {
public:
virtual void draw() = 0; // Pure virtual function
virtual double area() = 0; // Pure virtual function
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() override {
cout << "Drawing a circle" << endl;
}
double area() override {
return 3.14 * radius * radius;
}
};
class Square : public Shape {
private:
double side;
public:
Square(double s) : side(s) {}
void draw() override {
cout << "Drawing a square" << endl;
}
double area() override {
return side * side;
}
};
int main() {
Shape* shape1 = new Circle(5);
Shape* shape2 = new Square(4);
shape1->draw();
cout << "Circle area: " << shape1->area() << endl;
shape2->draw();
cout << "Square area: " << shape2->area() << endl;
delete shape1;
delete shape2;
return 0;
}
C++ Interfaces
In C++, interfaces are implemented as abstract classes with only pure virtual functions. Classes that implement the interface must provide their own implementation of these methods.
// Interface in C++
#include < iostream>
using namespace std;
class Printable {
public:
virtual void print() = 0; // Pure virtual function
};
class Document : public Printable {
public:
void print() override {
cout << "Printing Document" << endl;
}
};
class Image : public Printable {
public:
void print() override {
cout << "Printing Image" << endl;
}
};
int main() {
Printable* doc = new Document();
Printable* img = new Image();
doc->print();
img->print();
delete doc;
delete img;
return 0;
}
C++ Data Abstraction
Data abstraction is the concept of hiding the implementation details of an object and exposing only the relevant data and methods. This can be achieved in C++ through encapsulation and using classes to manage data.
// Data Abstraction in C++
#include < iostream>
using namespace std;
class BankAccount {
private:
double balance; // private member (data abstraction)
public:
BankAccount(double initial_balance) {
balance = initial_balance;
}
void deposit(double amount) {
if (amount > 0) {
balance += amount;
cout << "Deposited: " << amount << endl;
}
}
void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
cout << "Withdrew: " << amount << endl;
} else {
cout << "Insufficient balance" << endl;
}
}
double getBalance() {
return balance;
}
};
int main() {
BankAccount account(1000);
account.deposit(500);
cout << "Balance: " << account.getBalance() << endl;
account.withdraw(200);
cout << "Balance: " << account.getBalance() << endl;
account.withdraw(1500); // Insufficient funds
cout << "Balance: " << account.getBalance() << endl;
return 0;
}
C++ Namespaces
In C++, namespaces are used to organize code into logical groups and avoid name conflicts. A namespace is a container that holds identifiers (such as functions, classes, and variables) and allows them to be differentiated by their namespace.
The syntax for defining a namespace is as follows:
namespace namespace_name {` ... `}
Example of using namespaces:
// C++ Namespaces Example
#include < iostream>
using namespace std;
namespace Animal {
void sound() {
cout << "Animal makes a sound" << endl;
}
}
namespace Dog {
void sound() {
cout << "Dog barks" << endl;
}
}
int main() {
Animal::sound(); // Calls the sound function in the Animal namespace
Dog::sound(); // Calls the sound function in the Dog namespace
return 0;
}
C++ Strings
In C++, strings are used to store text. There are two types of strings in C++:
- C-style strings: Arrays of characters terminated by a null character (`'\0'`).
- C++ Standard Library Strings: The `std::string` class provides a more convenient and flexible way to work with text.
Example of using C++ strings:
// C++ Strings Example
#include < iostream>
#include < string>
using namespace std;
int main() {
string str = "Hello, World!";
cout << "String: " << str << endl;
// Using some string functions
cout << "Length of string: " << str.length() << endl;
cout << "Substring (from index 7): " << str.substr(7) << endl;
return 0;
}
C++ Templates
Templates in C++ allow writing generic programs. A template is a blueprint for creating classes or functions that can operate with any data type.
There are two types of templates:
- Function Templates: Used to create a generic function.
- Class Templates: Used to create a generic class.
Example of using a function template:
// C++ Function Template Example
#include < iostream>
using namespace std;
// Function template to add two values
template < typename T>
T add(T a, T b) {
return a + b;
}
int main() {
cout << "Addition of integers: " << add(5, 3) << endl; // Uses int
cout << "Addition of doubles: " << add(2.5, 3.7) << endl; // Uses double
return 0;
}
Example of using a class template:
// C++ Class Template Example
#include < iostream>
using namespace std;
// Class template to hold a pair of values
template < typename T, typename U>
class Pair {
private:
T first;
U second;
public:
Pair(T a, U b) : first(a), second(b) {}
void display() {
cout << "First: " << first << ", Second: " << second << endl;
}
};
int main() {
Pair< int, double> p1(5, 3.14);
p1.display();
Pair< string, int> p2("Age", 30);
p2.display();
return 0;
}
C++ Exceptions
Exceptions in C++ are used to handle runtime errors. These errors can arise due to various reasons such as invalid input, memory allocation failure, or attempting to divide by zero. C++ provides a structured way to handle exceptions using the `try`, `catch`, and `throw` keywords.
An exception is thrown when an error occurs, and it is caught by a corresponding `catch` block to handle the error appropriately.
// C++ Exception Handling Example
#include < iostream>
using namespace std;
int divide(int a, int b) {
if (b == 0) {
throw "Division by zero error!";
}
return a / b;
}
int main() {
try {
int result = divide(10, 0); // Will throw an exception
cout << "Result: " << result << endl;
}
catch (const char* msg) {
cout << "Caught an exception: " << msg << endl;
}
return 0;
}
C++ try/catch
In C++, the try block is used to define a section of code that may throw an exception. If an exception occurs within the try block, it is caught by the corresponding catch block.
The syntax is:
try {<code> ... </code>} catch (exception_type e) {<handle exception>}
Example of using try and catch:
// C++ try/catch Example
#include < iostream>
using namespace std;
int main() {
try {
int* ptr = nullptr;
cout << *ptr << endl; // Will cause a segmentation fault
}
catch (...) {
cout << "An exception occurred!" << endl; // Catch all exceptions
}
return 0;
}
C++ User-Defined Exceptions
In C++, you can also create custom exceptions by defining your own exception classes. These classes should inherit from the std::exception class, which is the base class for all exceptions in C++.
Example of defining and using user-defined exceptions:
// C++ User-Defined Exception Example
#include < iostream>
#include < exception>
using namespace std;
// Custom exception class
class DivisionByZeroException : public exception {
public:
const char* what() const noexcept override {
return "Division by zero is not allowed!";
}
};
int divide(int a, int b) {
if (b == 0) {
throw DivisionByZeroException(); // Throw custom exception
}
return a / b;
}
int main() {
try {
int result = divide(10, 0); // Will throw a user-defined exception
cout << "Result: " << result << endl;
}
catch (const DivisionByZeroException& e) {
cout << "Caught exception: " << e.what() << endl; // Handle custom exception
}
return 0;
}
C++ File & Stream
In C++, file handling is done using the <fstream> library, which provides functionality for reading from and writing to files. File streams can be categorized into three types:
- ifstream - Input file stream used for reading files.
- ofstream - Output file stream used for writing to files.
- fstream - A combination of both input and output file stream.
We open a file using the .open() method and close it using .close() method. Files can be opened in different modes such as read (ios::in), write (ios::out), append (ios::app), and more.
// C++ File Handling Example
#include < iostream>
#include < fstream>
using namespace std;
int main() {
ofstream outputFile("example.txt"); // Create and open a file for writing
if (!outputFile) { // Check if file is open successfully
cout << "Error opening file!" << endl;
return 1;
}
// Write to the file
outputFile << "This is a test file." << endl;
outputFile << "Writing to the file is easy." << endl;
outputFile.close(); // Close the file
// Read from the file
ifstream inputFile("example.txt"); // Open the file for reading
if (!inputFile) {
cout << "Error opening file for reading!" << endl;
return 1;
}
string line;
while (getline(inputFile, line)) { // Read lines from the file
cout << line << endl; // Output the lines
}
inputFile.close(); // Close the file
return 0;
}
C++ getline()
The getline() function is used to read an entire line from an input stream. Unlike the standard cin, getline() reads a line of text, including spaces, until a newline character ('\n') is encountered.
The syntax for getline() is as follows:
getline(input_stream, string_variable);
This function is commonly used to read input from files or standard input (keyboard), and it’s especially useful when you want to read multi-word strings or whole lines.
// C++ getline() Example
#include < iostream>
#include < fstream>
#include < string>
using namespace std;
int main() {
ifstream inputFile("example.txt"); // Open a file for reading
if (!inputFile) {
cout << "Error opening file!" << endl;
return 1;
}
string line;
while (getline(inputFile, line)) { // Read each line from the file
cout << "Read line: " << line << endl; // Display the line
}
inputFile.close(); // Close the file
return 0;
}
Conclusion
Congratulations! You’ve now covered the fundamental concepts of C++ programming, from basic syntax and operators to advanced topics like object-oriented programming, file handling, and exception handling. You have learned how to write, read, and manage files, use dynamic memory management, and implement key OOP principles such as inheritance, polymorphism, and abstraction.
C++ is a powerful and versatile language, widely used for system software, game development, embedded systems, and performance-critical applications. With its rich feature set, you can create efficient, complex, and scalable software systems.
As you move forward, here are some future directions and career guidance:
- Advanced C++ Topics: To further strengthen your C++ skills, dive deeper into advanced topics like multi-threading, design patterns, and performance optimization techniques. Learning about modern C++ standards (C++11, C++14, C++17, C++20) will help you stay up to date with the latest language features.
- Data Structures and Algorithms: Mastering data structures (like trees, graphs, and heaps) and algorithms (sorting, searching, etc.) will significantly enhance your ability to solve complex problems efficiently.
- Game Development: C++ is a primary language for game development, with engines like Unreal Engine relying on it. If you're interested in games, learning more about game engines and graphics programming could be your next step.
- System Programming: C++ is widely used in system-level programming (OS, device drivers). Deepening your knowledge in this domain will give you insight into how operating systems work and can open opportunities in low-level development.
- Open-Source Contribution: Get involved in C++ open-source projects to gain real-world experience and collaborate with a community of like-minded developers. GitHub is a great place to find such projects.
To take your learning to the next level, consider building personal projects, contributing to open-source software, or pursuing certifications in C++ programming. Whether you aim for a career as a software engineer, systems architect, or embedded systems developer, mastering C++ will open doors to numerous opportunities in the tech industry.