Page 1 of 28
Overview of C++
C++ is an object-oriented programming language with support for standard libraries and generic programming.
Key Features:
- Procedural Techniques
- Core Library: Data types, variables
- Standard Library (STL): Strings, files
Basic Input/Output (I/O)
C++ uses the stream concept for input and output operations:
- cout:
ostreamclass object - cin:
istreamclass object - endl:
ostream
C++ Variables
Variables in C++ can be defined using:
- Alphabets
- Underscores
C++ Data Types
C++ supports the following types of data:
- Basic:
int,char,float, etc. - Derived: Arrays, pointers
- Enumeration:
enum - User-defined:
struct
Operators
- Comma Operator: Evaluates expressions from left to right.
- Assignment Operator: Assigns values from right to left.
Code Statements
Label:
goto label;
Loop:
for (int i = 0; i < n; i++) {
// loop body
}
Preprocessor
A program that runs before compilation.
Workflow Diagram:
flowchart TD
A[Source File] --> B[Preprocessor]
B --> C[Compiler]
C --> D[Linker]
D --> E[Executable File]
E --> F[Command Execution]
Page 2 of 28
Preprocessor Directives
#include
- Commonly used preprocessor directive.
- Syntax:
#include <stdio.h>: Looks for paths in predefined directories.#include "filename.h": Looks for relative paths.
#define
Defines macros.
#define identifier char-sequence
#undef
Undefines macros.
#undef macro-name
Conditional Compilation:
#if condition
// code
#elif condition
// code
#else
// code
#endif
Macro Checking:
#ifdef macro-name
// code
#endif
#ifndef macro-name
// code
#endif
## Operator
Used with #define macros to concatenate tokens.
#define AA(a, b) a ## b
Example:
For 3, 4:
= 34 * 3 * 4
Page 3 of 28
Inline Functions
- Inline: A request to optimize function calls.
- Benefits: Improves speed by reducing function overhead.
- Compiler Exceptions:
- Functions with loops, switch, or goto statements.
- Recursive functions.
- Functions with static variables.
Example:
inline void fun() {
// function body
}
Default Arguments
Allows default values for function parameters.
int add(int a, int b = 0);
Function Overloading
C++ allows multiple functions with the same name but different parameter types.
Matching Rules:
- Exact match with parameter type.
- Promotion of types (e.g.,
char→int,float→double). - If no match is found, standard conversion is attempted.
Page 4 of 28
Structure Encapsulation
Encapsulation combines properties and methods into a single entity.
Example:
struct book {
int id;
float price;
void input() {
cin >> id >> price;
}
void display() {
cout << id << " " << price;
}
};
int main() {
book b1;
b1.input();
b1.display();
return 0;
}
Structure Security (Data Hiding)
Encapsulation ensures data hiding by using access specifiers.
Example:
struct book {
private:
int id;
float price;
public:
void input() {
cin >> id >> price;
}
};
int main() {
book b1;
b1.input();
return 0;
}
Page 5 of 28
Classes and Objects in C++
The only difference between structures and classes is:
- Members of structures are by default public.
- Members of classes are by default private.
Example Code:
class Complex {
int a, b;
public:
void show_data();
};
void Complex::show_data() {
cout << "Wow";
cout << a;
}
Static Members:
Static Local Variables:
- Static local variable exists in memory only after the program starts.
- By default, it is set to 0.
Example Code:
void fun() {
static int x = 10;
int y;
}
Static Member Variables:
- Declared inside the class body.
- Also called class member variables.
- Must be defined outside the class.
- Can be accessed via
Account::roi = 4.5f.
Example Code:
class Account {
private:
int balance;
static float roi;
};
float Account::roi = 3.5f;
Page 6 of 28
Static Member Functions:
- Also called class member functions.
- They can be invoked with or without an object.
Constructors:
Key Points:
- A constructor is a member function of a class.
- It has no return type.
- It must be an instance member function (can't be static).
- Name of constructor = Name of class.
How to Call Constructor?
- A constructor gets invoked when an object is created.
- It solves the problem of initialization.
Types of Constructors:
-
Default Constructor:
- A constructor which has no arguments.
- Invoked for creating an object.
-
Parameterized Constructor:
- Example:
Complex c1(3,4), c2(5);- Overloading is possible in constructors.
Also compiler adds default constructor if no constructor is given→ Corrected: Also, the compiler adds a default constructor if none is defined.
Page 7 of 28
Example Code:
Complex c1 = 5;
Complex c1;
Complex c1 = Complex(3,4); // Canonicalized way
Complex c1(3,4);
Note:
- If public access specifier is not given to constructors, objects cannot be created.
Copy Constructor:
Key Points:
- If there is no constructor in a class, the compiler will add two constructors (for C++, not Java):
- Default Constructor
- Copy Constructor
- Called when:
Complex c1(c2);
Example Code:
Complex(const Complex &c) {
a = c.a;
b = c.b;
}
Notes:
-
If instead of a reference variable, a Complex c parameter is given, it will lead to memory stack overflow due to recursion.
-
Also, try to use
constbecause: We definitely don't want to modify the object. -
Copy constructors need not be defined unless it involves dynamic memory or runtime things.
Destructors:
Key Points:
- A destructor is an instance member function (can't be static).
- Symbolized by
~. - No return type.
- Name of destructor = Name of class.
- No arguments in destructors; no overloading is possible.
- It is invoked implicitly when the object is going to be destroyed.
Page 8 of 28
Why Destructor?
- Should be defined to release resources allocated to an object.
Operator Overloading:
Example Code:
class Complex {
int a, b;
public:
Complex operator+(Complex c) {
Complex temp;
temp.a = a + c.a;
temp.b = b + c.b;
return temp;
}
};
int main() {
Complex c3 = c1 + c2; // Equivalent to: c3 = c1.operator+(c2);
}
Notes:
- Sizeof and conditional operators cannot be overloaded.
::and.also cannot be overloaded.
Overloading Post & Pre-Increment:
(Content not fully elaborated; placeholder for further details.)
Page 9 of 28
Class Integer Example with Operator Overloading
class Integer {
int x;
public:
Integer operator++() { // Pre-Increment
Integer i;
i.x = ++x;
return i;
}
Integer operator++(int) { // Post-Increment
Integer i;
i.x = x++;
return i;
}
};
Friend Functions
-
Definition:
- It is not a member function of a class to which it is a friend.
- It is declared using the
friendkeyword but must be defined outside the class to which it is a friend.
-
What can it access?
- It can access any members of the class to which it is a friend.
- It cannot access members of the class directly.
Example:
class Complex {
int a, b;
public:
friend void fun(); // Friend function declaration
};
void fun() {
Complex c;
cout << c.a << c.b; // Access private members of Complex
}
int main() {
fun();
}
Page 10 of 28
Friend Function with Multiple Classes
- A friend function can become a friend to more than one class.
Overloading Insertion (<<) & Extraction (>>) Operators
Example:
class Complex {
int a, b;
public:
friend ostream& operator<<(ostream&, Complex&);
friend istream& operator>>(istream&, Complex&);
};
ostream& operator<<(ostream &dout, Complex &c) {
dout << c.a << " " << c.b;
return dout;
}
istream& operator>>(istream &din, Complex &c) {
din >> c.a >> c.b;
return din;
}
int main() {
Complex c1, c2;
cin >> c1 >> c2;
cout << c1 << " " << c2;
}
Page 11 of 28
Friend Class
Example:
class A {
public:
void fun() {}
void foo() {}
};
class B {
public:
friend void fun(); // Friend function
friend class A};
- Key Note: Both ways of access are acceptable.
Inheritance
- Definition: Reuse members of parent class.
- Visibility Modes:
public,private,protected.
Types of Inheritance:
- Single Inheritance:
classDiagram class A class D A --> D
- Multilevel Inheritance:
classDiagram class A class B class C A --> B B --> C
- Multiple Inheritance:
classDiagram class A class B class C A --> C B --> C
- Hierarchical Inheritance:
classDiagram class A class B class D A --> B A --> D
- Hybrid Inheritance:
classDiagram class A class B class C class D A --> B A --> C B --> D C --> D
Page 12 of 28
Accessibility in Inheritance
Accessibility Modes:
| Accessibility Mode | Available To | Examples |
|---|---|---|
| Private | Class itself | Available only to base class |
| Protected | Derived class | Available to derived classes |
| Public | All | Available to all accessible objects |
Notes:
- The protected and public variables are inherited in derived classes.
- Private variables/functions will remain private to the derived class.
Constructors in Inheritance
Example:
class A {
public:
A() { cout << "A"; }
};
class B : public A {
public:
B() { cout << "B"; }
};
Key Behavior:
- Runs from parent to child but calls from child to parent.
Page 13 of 28
Destructors in Inheritance
class B : public A {
public:
~B() {
// Destructor logic
}
};
this Pointer:
The pointer containing the address of the object is called the Object Pointer.
graph LR
p["Pointer to Address"] --> obj1["Object 1"]
p --> obj2["Object 2"]
p --> obj3["Object 3"]
p->lis same asobj.l.thisis a local object pointer in every instance member function containing the address of the caller object.thispointer cannot be modified.- Code Example:
this->l = l;
Page 14 of 28
new & delete
int *p = new int;
float *q = new float;
Complex *ptr = new Complex;
int *p = new int[10];
// Deallocation
delete p;
delete q;
delete ptr;
delete[] p; // For arrays
Polymorphism (Many Forms)
Types of Polymorphism:
- Compile-Time (C.T.):
- Function Overloading
- Operator Overloading
- Run-Time (R.T.):
- Method Overloading
- Virtual Functions
Method Hiding Example:
class A {
public:
void f1() { /* Function logic */ }
void f2() { /* Function logic */ }
};
class B : public A {
public:
void f1() { /* Function logic */ }
void};
B obj;
}
- Method Overloading: This hides the parent methods and replaces them with child methods.
Page 15 of 28
Virtual Functions
Why Virtual Functions?
- To enable late binding (runtime binding).
Example:
class A {
public:
virtual void f() { /* Function logic */ }
};
class B : public A {
public:
void f() { /* Function logic */ }
};
void main() {
A *p;
B obj;
p = &obj;
p->}
- Without
virtual, it performs early binding and callsA::f().
Page 16 of 28
Templates in C++
Function Template:
template <class X>
X func_name(X arg1, X arg2) {
// Function logic
}
template <class X, class Y>
X func_name(X arg1, Y arg2) {
// Function logic
}
Explanation:
- Generic Programming is a style of programming where algorithms are written in terms of types to be specified later. These are instantiated when needed for specific types provided as parameters.
- The
templatekeyword is used to define:- Function Template
- Class Template
Class Template Example:
template <class X>
class A {
// Class logic
};
A<int> obj1; // Instantiation with int type
A<float> obj2; // Instantiation with float type
Note: Templates can also be overloaded.
Page 17 of 28
File Handling
Diagram of File Handling Classes
classDiagram
class OS {
<<Root>>
}
OS <|-- istream
OS <|-- ostream
istream <|-- iostream
ostream <|-- iostream
istream <|-- istream-withassign
ostream <|-- ostream-withassign
Code Example: Writing to a File
#include <fstream>
ofstream fout;
fout.open("myfile.dat"); // Creates a file & moves it to RAM
fout << "Hello"; // Writes only to RAM
fout.close(); // Moves data to HDD
Code Example: Reading from a File
ifstream fin;
fin.open("myfile.dat");
char ch;
fin >> ch;
while (!fin.eof()) {
cout << ch;
fin >> ch;
}
fin.close();
Page 18 of 28
File Opening Modes
| Mode | Description |
|---|---|
ios::in | Input/read |
ios::out | Output/write |
ios::app | Append |
ios::ate | Update |
ios::binary | Binary |
Example: Opening a File
fstream fout;
fout.open("myfile.dat", ios::out);
// Default is ios::out | ios::binary
Note: Multiple inputs can be combined using OR (|).
In binary mode, special characters are translated, e.g., '\n'.
tellg and tellp Functions
ifstream fin;
fin.open("abc.txt");
cout << fin.tellg(); // Returns position of current character
fin.close();
Page 19 of 28
seekg and seekp Functions
ifstream fin;
fin.open("abc.txt");
fin.seekg(pos); // Moves to position `pos`
fin.seekg(+2, ios::base::cur); // Offset from current position
// ios::base::beg -> from beginning
// ios::base::cur -> from current position
Note: seekp is similar but for ofstream class objects.
Initializer List
Definition
- Initializer List is used to initialize data members of a class.
- The list of members to be initialized is indicated within the constructor as a comma-separated list followed by a colon.
Example
class Dummy {
private:
int a, b;
public:
Dummy() : a(5), b(6) {}
};
Page 20 of 28
Usage of Initializer List
This can be used for:
- Const Variables
- Reference Variables
Example
int &n;
public:
Dummy(int &n) : n(n) {}
Deep Copy and Shallow Copy
Definitions
- Deep Copy: Creating a copy of an object by copying all values of temporary memory allocated outside the object.
- Shallow Copy: Creating a copy of an object by copying data of all members stored in it.
Notes
- Either copy constructor is called or implicit copy assignment operator is used.
Example
void main() {
Dummy d1;
d1.setData(5, 6);
Dummy d2;
d2 = d1; // Copy assignment operator called
}
Page 21 of 28
Deep Copy and Shallow Copy
Diagram:
classDiagram
class d2 {
a : 2
b : 3
}
class d1 {
a : 2
b : 3
}
class p {
value : 10
}
d2 --> p
d1 --> p
Explanation:
Here, p doesn't → does not get new memory.
So, we need deep copy.
Dummy(Dummy fd) {
a = d.a;
b = d.b;
b = new int;
*b = *(d.b);
}
Also, shallow copy may lead to dangling pointers.
Type Conversion (Primitive to Class)
Examples:
float n = 34;
int y = n; // Automatic type conversion
Complex c1;
int x = 5;
c1 = x; // Error
Primitive to Class:
It can be implemented through constructors.
class Complex {
int a, b;
public:
Complex(int k) {
a = k; b = 0;
}
};
Page 22 of 28
Type Conversion Continued
II. Class to Primitive:
It can be implemented with a casting operator.
operator type() {
return (type data);
}
Example:
int x = c1; // Error
Complex c2;
x = c2.operator int();
III. Class to Class:
It can be implemented with either constructors or a casting operator.
Exceptions
Definition:
Any abnormal behavior or runtime error.
Syntax:
try {
// Code block
}
catch (type1 arg) {
// Handle exception of type1
}
catch (type2 arg) {
// Handle exception of type2
}
Notes:
throwis used to throw an exception.argis optional.typecan be any type (user-defined or primitive).throwis optional; there is also a stack trace.
Page 23 of 28
Dynamic Constructors
Definition:
Constructors can allocate dynamically created memory to the object.
Explanation:
Thus, the object is assigned to a memory region which is dynamically created by the constructor.
class C {
int *p; // Wild pointer
public:
C() {
p = new int;
}
};
Namespaces
Header File:
#include <iostream>
- Header file: Contains identifier declarations.
- Library file: Contains identifier definitions.
Syntax:
namespace myspace {
// Declaration of group
}
So, myspace is a name of the group.
Page 24 of 28
Namespaces Continued
Definition:
A namespace is a container for identifiers.
It puts the name of its members in a distinct space so that they do not conflict with the names in other namespaces or global namespace.
Notes:
- Namespace definition must be done at global scope or nested inside another namespace.
- Example:
namespace ms {
int a;
}
Example with Diagram:
classDiagram
class ms {
int a : 3
}
class std {
cout : "output stream"
}
class iostream {
cin : "input stream"
}
Scope Resolution:
using namespace std; // If a variable or function name is same, then ambiguous
using namespace ms;
ms::a = 3;
ms::A::func(); // Using scope resolution
Using Keyword:
Using keyword allows importing an entire namespace into a program with global scope.
Page 25 of 28
STL (Standard Template Library)
It is a powerful set of C++ template classes.
At the core of C++, STL areas:
- Containers
- Algorithms
- Iterators
Containers:
Manage collections of objects of a certain kind.
They are generic.
Algorithms:
Initialization, sorting, searching, and transforming of the contents of containers.
Iterators:
Bridge between containers and algorithms.
Point to the containers.
Containers
Array
#include <array>
array<int, size> arr;
arr[num] // Access using index
arr.at(num);
arr.front(); // First element
arr.back(); // Last element
arr.fill(10); // Fill all elements with value 10
arr.begin();
arr.end();
Page 26 of 28
Tuple
#include <tuple>
tuple<t1, t2, t3> tp;
make_tuple();
get<0>(tp);
String
#include <string>
string s1, s2;
s1 = "Hello";
s1("Hello");
s1(CharArray);
Operators:
+→ Concatenate strings=→ Assign strings<→ Compare strings lexicographically>→ Compare strings lexicographically
Methods:
s1.assign("str");
s1 += "str"; // Append string
s1.insert(index, "str");
s1.replace(index, len, "str");
s1.erase(index);
s1.find("str"); // Returns index or -1
s1.compare("str"); // Returns 0, -1, or 1
s1.size();
Page 27 of 28
C++ Polymorphism (Many forms)
Types of Polymorphism
- Compile Time (CT Poly)
- Function Overloading
- Operator Overloading
- Run Time (RT Poly)
- Virtual Functions
Function Overloading
Some function names but different parameters.
Operator Overloading
Same operator used in objects, etc.
Method Overloading, Overriding, and Hiding
class A {
public:
void sum1() {
// Implementation
}
void sum2() {
// Implementation
}
};
class B : public A {
public:
void sum1() {
// Method Overriding }
}
};
}
Page 28 of 28
The same can be achieved with data members.
class A {
public:
int x = 39, y = 4;
};
class B : public A {
public:
int x = 2;
string y = "Dog";
};
cout << x; // Outputs 2
cout << y; // Outputs "Dog"
References and Related Topics:
- Object-Oriented Programming in C++
- C++ Standard Template Library (STL)
- Preprocessor Directives in C++
- Function Overloading and Inline Functions
- Encapsulation and Data Hiding in C++