This complete C++ tutorial covers 111 topics — from language fundamentals and OOP to STL, smart pointers, modern standards, and a final C++ application project.
Course roadmap
- Introduction to C++
- What is C++?
- Features of C++
- C vs C++
- Installing a C++ Compiler
- Setting Up VS Code for C++
- First C++ Program
- C++ Program Structure
- Compilation and Execution in C++
- C++ Syntax
- Comments in C++
- Variables and Constants in C++
- Data Types in C++
- Type Casting in C++
- Input and Output in C++
- cin, cout and cerr in C++
- Operators in C++
- Arithmetic Operators in C++
- Relational Operators in C++
- Logical Operators in C++
- Assignment Operators in C++
- Bitwise Operators in C++
- Conditional Operator in C++
- Conditional Statements in C++
- if, else if and else in C++
- Nested if in C++
- switch Statement in C++
- Loops in C++
- for Loop in C++
- while Loop in C++
- do-while Loop in C++
- break and continue in C++
- Functions in C++
- Function Parameters in C++
- Return Values in C++
- Function Overloading in C++
- Default Arguments in C++
- Inline Functions in C++
- Recursion in C++
- Arrays in C++
- Multidimensional Arrays in C++
- Strings in C++
- C-Style Strings in C++
- std::string in C++
- String Methods in C++
- Pointers in C++
- References in C++
- Pointer Arithmetic in C++
- Dynamic Memory Allocation in C++
- new and delete in C++
- Classes and Objects in C++
- Constructors in C++
- Destructors in C++
- this Pointer in C++
- Access Modifiers in C++
- Encapsulation in C++
- Inheritance in C++
- Types of Inheritance in C++
- Multiple Inheritance in C++
- Multilevel Inheritance in C++
- Hierarchical Inheritance in C++
- Polymorphism in C++
- Function Overriding in C++
- Virtual Functions in C++
- Pure Virtual Functions in C++
- Abstract Classes in C++
- Operator Overloading in C++
- Friend Functions in C++
- Static Members in C++
- const Members in C++
- Templates in C++
- Function Templates in C++
- Class Templates in C++
- Exception Handling in C++
- try, catch and throw in C++
- File Handling in C++
- Reading and Writing Files in C++
- Header Files in C++
- Namespaces in C++
- Preprocessor Directives in C++
- Standard Template Library (STL) in C++
- std::vector in C++
- std::list in C++
- std::deque in C++
- std::stack in C++
- std::queue in C++
- std::priority_queue in C++
- std::set in C++
- std::multiset in C++
- std::map in C++
- std::multimap in C++
- Iterators in C++
- STL Algorithms in C++
- Lambda Expressions in C++
- Smart Pointers in C++
- std::unique_ptr in C++
- std::shared_ptr in C++
- std::weak_ptr in C++
- Move Semantics in C++
- Multithreading in C++
- C++ Modern Features
- C++11, C++14, C++17 and C++20
- Debugging C++ Applications
- Memory Management Best Practices in C++
- C++ Coding Standards
- Data Structures and Algorithms with C++
- Searching and Sorting in C++
- C++ Interview Questions
- C++ Programming Practice
- Real-World C++ Project
- Final Project – Complete C++ Application
1. Introduction to C++
C++ is a high-performance multi-paradigm language used in systems, games, finance, and embedded software. This series covers core language, OOP, STL, smart pointers, modern C++, and a complete application project.
- Install a C++ toolchain and compile Hello World.
- Learn OOP, STL, and modern features.
- Build the final C++ application project.
Learning path
Setup + first program
Types + control flow + functions
OOP + inheritance + polymorphism
STL + templates + exceptions
Modern C++ + concurrency
Final C++ application
2. What is C++?
C++ supports procedural, object-oriented, and generic programming while staying close to the metal for performance.
C++ at a glance
Compiled, multi-paradigm
Zero-overhead abstractions goal
STL + standard library
Used in systems/games/finance/tools
3. Features of C++
Modern C++ emphasizes safety and expressiveness without sacrificing speed when used well.
Feature highlights
Classes & OOP
Templates / generics
RAII & deterministic destruction
Operator overloading
STL containers/algorithms
Move semantics (modern)
4. C vs C++
C is mostly procedural; C++ adds classes, templates, exceptions, and a larger standard library — with different idioms.
Quick compare
C → simpler core, manual patterns
C++ → OOP + STL + modern abstractions
Interop possible carefully
Choose by domain & team skills
5. Installing a C++ Compiler
On Windows, MSYS2/MinGW-w64 or Visual Studio Build Tools are common choices.
- Install a C++ compiler toolchain.
- Add it to PATH.
- Verify with –version.
Verify
g++ --version
# or
clang++ --version
6. Setting Up VS Code for C++
Compile with `g++ -std=c++17 -Wall -Wextra file.cpp -o file` and run from the terminal.
Compile tip
g++ -std=c++17 -Wall -Wextra main.cpp -o main
./main
7. First C++ Program
Confirm your toolchain before diving into language details.
- Create main.cpp.
- Compile with g++.
- Run the executable.
Hello World
#include <iostream>
int main() {
std::cout << "Hello, C++!n";
return 0;
}
8. C++ Program Structure
Typical flow: headers → using/namespace choices → main → helpers.
Structure
#include headers
optional using declarations
int main() { ... }
free functions / classes
9. Compilation and Execution in C++
Object files link with the C++ standard library into an executable.
Stages
Preprocess
Compile (.cpp → .o)
Link (objects + libs)
Run
10. C++ Syntax
C++ is case-sensitive; prefer clear names and consistent style.
Syntax sample
int x = 10;
if (x > 0) {
std::cout << "positiven";
}
11. Comments in C++
Explain why; keep comments updated.
Comments
// Single line
/* Multi-line
comment */
12. Variables and Constants in C++
Initialize before use; prefer const by default when values don’t change.
Variables
int count = 0;
const double pi = 3.14159;
constexpr int max_n = 100;
13. Data Types in C++
Prefer <cstdint> fixed-width types when sizes must be portable.
Type map
int, char, bool, float, double
unsigned / long variants
std::size_t, std::string
int32_t / int64_t when needed
14. Type Casting in C++
Prefer named casts over C-style casts for clarity and safety.
static_cast
double d = 3.7;
int n = static_cast<int>(d); // 3
15. Input and Output in C++
Prefer formatted IO carefully; validate user input.
I/O idea
std::cin → input
std::cout → output
std::cerr → errors
std::getline for lines
16. cin, cout and cerr in C++
cerr is typically unbuffered — good for diagnostics.
cin/cout/cerr
int age;
std::cout << "Age: ";
if (std::cin >> age) {
std::cout << "You are " << age << 'n';
} else {
std::cerr << "Invalid inputn";
}
17. Operators in C++
Know precedence; overload operators carefully for class types.
Operator groups
Arithmetic
Relational
Logical
Bitwise
Assignment
Ternary ?:
18. Arithmetic Operators in C++
Integer division truncates toward zero (since C++11 for integers).
Arithmetic
int a = 10, b = 3;
int q = a / b; // 3
int r = a % b; // 1
19. Relational Operators in C++
For class types, define comparisons intentionally (or use defaulted C++20 spaceship where appropriate).
Relational
if (x >= 0 && x <= 100) {
/* in range */
}
20. Logical Operators in C++
Useful for null/optional-style guards.
Logical
if (ptr && ptr->ready()) {
ptr->run();
}
21. Assignment Operators in C++
For classes, know Rule of Five/Zero around copy/move assignment.
Assignment
int n = 5;
n += 2; // 7
22. Bitwise Operators in C++
Common for flags and low-level protocols.
Bitwise
unsigned flags = 0;
flags |= 1u << 3;
flags &= ~(1u << 3);
23. Conditional Operator in C++
Keep ternaries readable; avoid deep nesting.
Ternary
int abs_x = (x < 0) ? -x : x;
24. Conditional Statements in C++
Prefer early returns to reduce nesting in larger functions.
Branching tools
if / else if / else
nested if
switch
25. if, else if and else in C++
Brace bodies consistently for maintainability.
if/else
if (score >= 50) {
std::cout << "Passn";
} else if (score >= 40) {
std::cout << "Retaken";
} else {
std::cout << "Failn";
}
26. Nested if in C++
Extract helper predicates for clarity.
Nested if tip
Keep depth shallow
Use else-if ladders
Extract bool helpers
27. switch Statement in C++
C++17+ supports init-statements in switch; C++17+ also has if with initializer.
switch
switch (op) {
case '+':
result = a + b;
break;
default:
std::cerr << "unknownn";
}
28. Loops in C++
Prefer range-based for for containers when you don’t need indices.
Loop choices
for / while / do-while
range-based for
algorithms (for_each, transform)
29. for Loop in C++
Range-for is idiomatic for STL containers.
for + range-for
for (int i = 0; i < n; ++i) { /* ... */ }
for (const auto& item : items) { /* ... */ }
30. while Loop in C++
Ensure progress toward termination.
while
int n = 3;
while (n > 0) {
std::cout << n << 'n';
--n;
}
31. do-while Loop in C++
Useful for menus and retry prompts.
do-while
int choice;
do {
std::cout << "1) Run 0) Quitn";
std::cin >> choice;
} while (choice != 0);
32. break and continue in C++
Use carefully for readability.
break/continue
for (int i = 0; i < 10; ++i) {
if (i % 2 == 0) continue;
if (i > 7) break;
std::cout << i << 'n';
}
33. Functions in C++
Prefer declarations in headers and definitions in .cpp for larger projects.
Function
int add(int a, int b) {
return a + b;
}
34. Function Parameters in C++
Prefer `const T&` for large read-only objects.
Parameters
void print_name(const std::string& name) {
std::cout << name << 'n';
}
35. Return Values in C++
Prefer return values for clarity; structured bindings help multi-returns.
Return
double square(double x) {
return x * x;
}
36. Function Overloading in C++
Return type alone cannot overload; signatures must differ.
Overload
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
37. Default Arguments in C++
Declare defaults in the declaration (header) typically.
Defaults
void greet(const std::string& name = "Guest") {
std::cout << "Hi " << name << 'n';
}
38. Inline Functions in C++
Modern compilers decide inlining; inline often matters for header-defined functions.
Inline tip
OK for small header functions
Compiler may ignore for optimization
Important for ODR with header definitions
39. Recursion in C++
Watch stack depth; prefer iterative/STL algorithms when simpler.
Recursion
long factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
40. Arrays in C++
Built-in arrays don’t know their size at runtime.
Array tip
int a[5] = {1, 2, 3, 4, 5};
std::array<int, 5> b = {1, 2, 3, 4, 5};
41. Multidimensional Arrays in C++
`vector<vector<T>>` is flexible; contiguous 1D with indexing can be faster.
2D idea
int grid[2][3] = {{1, 2, 3}, {4, 5, 6}};
42. Strings in C++
Know when C-style strings appear (C APIs, literals).
string
#include <string>
std::string name = "Asha";
43. C-Style Strings in C++
Easy to overflow — prefer std::string unless required.
C-string
char name[32] = "Asha";
44. std::string in C++
Use size()/empty() and range-for for iteration.
std::string
std::string s = "Hello";
s += ", C++";
std::cout << s.size() << 'n';
45. String Methods in C++
Beware iterator invalidation after modifying operations.
Methods
auto pos = s.find("C++");
if (pos != std::string::npos) {
auto part = s.substr(pos);
}
46. Pointers in C++
Raw pointers are fine for non-owning observation.
Pointer
int x = 10;
int* p = &x;
std::cout << *p << 'n';
47. References in C++
const T& for read-only params; T& for mutable aliases.
Reference
int x = 5;
int& r = x;
r = 7; // x is 7
48. Pointer Arithmetic in C++
Prefer iterators/indices over raw pointer arithmetic in application code.
Pointer arithmetic
int a[3] = {10, 20, 30};
int* p = a;
std::cout << *(p + 1) << 'n'; // 20
49. Dynamic Memory Allocation in C++
Prefer RAII containers/smart pointers over naked new/delete.
Modern preference
std::vector / std::string
std::unique_ptr / shared_ptr
Avoid manual new/delete when possible
50. new and delete in C++
Never mix new with free, or new[] with delete.
new/delete
int* p = new int(42);
// ...
delete p;
p = nullptr;
51. Classes and Objects in C++
Start with clear public APIs and private data.
Class
class User {
public:
explicit User(std::string name) : name_(std::move(name)) {}
const std::string& name() const { return name_; }
private:
std::string name_;
};
52. Constructors in C++
Prefer member initializer lists; mark single-arg constructors explicit when conversions are undesirable.
Constructor
struct Point {
Point(int x, int y) : x_(x), y_(y) {}
int x_, y_;
};
53. Destructors in C++
If you manage raw resources, follow Rule of Five/Zero.
Destructor tip
Automatic at scope end
RAII: acquire in ctor, release in dtor
virtual ~Base() if deleting via base pointer
54. this Pointer in C++
Useful for disambiguation and fluent interfaces returning *this.
this
User& set_name(std::string name) {
this->name_ = std::move(name);
return *this;
}
55. Access Modifiers in C++
Default access is private for class, public for struct.
Access
public → API
private → internals
protected → derived access
56. Encapsulation in C++
Expose behavior, not raw fields, when invariants matter.
Encapsulation tip
Private data
Public methods
Maintain invariants
Minimize friend usage
57. Inheritance in C++
Prefer public inheritance for is-a relationships; favor composition often.
Inheritance
class Animal {
public:
virtual ~Animal() = default;
virtual void speak() const = 0;
};
class Dog : public Animal {
public:
void speak() const override { std::cout << "Woofn"; }
};
58. Types of Inheritance in C++
Multiple inheritance needs care with ambiguity and virtual bases.
Inheritance forms
Single
Multiple
Multilevel
Hierarchical
Hybrid
59. Multiple Inheritance in C++
Watch diamond problems — use virtual inheritance when appropriate.
Multiple inheritance tip
Useful for interfaces/mixins
Ambiguity risk
Prefer small interface bases
60. Multilevel Inheritance in C++
Keep hierarchies shallow for maintainability.
Multilevel tip
Grandparent → Parent → Child
Don't over-deepen
Prefer composition if reuse isn't is-a
61. Hierarchical Inheritance in C++
Common for shape/animal hierarchies in teaching and UI widgets in practice.
Hierarchical tip
One base, many derived
Virtual functions for shared interface
virtual destructor in base
62. Polymorphism in C++
Call through base pointers/references for runtime dispatch.
Polymorphism
std::unique_ptr<Animal> a = std::make_unique<Dog>();
a->speak();
63. Function Overriding in C++
Use override keyword to catch signature mismatches.
override
void speak() const override {
std::cout << "Woofn";
}
64. Virtual Functions in C++
Virtual calls require a virtual table; don’t forget virtual destructors.
Virtual tip
virtual in base
override in derived
virtual ~Base()
Dispatch via pointer/reference
65. Pure Virtual Functions in C++
A class with pure virtuals is abstract — cannot instantiate.
Pure virtual
class Shape {
public:
virtual ~Shape() = default;
virtual double area() const = 0;
};
66. Abstract Classes in C++
Keep abstract bases focused; prefer pure interfaces + composition.
Abstract tip
Cannot instantiate
Forces overrides
Good for plugin-like designs
67. Operator Overloading in C++
Overload only when meaning is obvious (e.g., + for vectors, << for printing).
operator<< tip
std::ostream& operator<<(std::ostream& os, const Point& p) {
return os << '(' << p.x_ << ',' << p.y_ << ')';
}
68. Friend Functions in C++
Use sparingly — prefer public API; friends are for symmetric operators sometimes.
Friend tip
Breaks encapsulation carefully
Common for operator<<
Minimize friend surface
69. Static Members in C++
Define static data members out-of-line (unless inline/constexpr).
Static
class Counter {
public:
static int created;
Counter() { ++created; }
};
int Counter::created = 0;
70. const Members in C++
const-correctness enables safer APIs and overloading on const.
const method
const std::string& name() const { return name_; }
71. Templates in C++
Templates enable static polymorphism and STL-style generic programming.
Template idea
template <typename T>
T max_value(T a, T b) {
return (a < b) ? b : a;
}
72. Function Templates in C++
Let compiler deduce template arguments when possible.
Function template
template <typename T>
void print_all(const std::vector<T>& v) {
for (const auto& x : v) std::cout << x << ' ';
}
73. Class Templates in C++
Most class templates live in headers due to instantiation rules.
Class template
template <typename T>
class Box {
public:
explicit Box(T value) : value_(std::move(value)) {}
const T& get() const { return value_; }
private:
T value_;
};
74. Exception Handling in C++
Prefer RAII so exceptions don’t leak resources; don’t use exceptions for normal control flow.
Exceptions tip
throw on hard failures
catch by const reference
RAII for cleanup
noexcept where appropriate
75. try, catch and throw in C++
Catch std::exception const& for standard errors.
try/catch
try {
throw std::runtime_error("boom");
} catch (const std::exception& ex) {
std::cerr << ex.what() << 'n';
}
76. File Handling in C++
Always check if streams opened successfully.
fstream checklist
ifstream / ofstream / fstream
check is_open or boolean state
close via RAII destructor
77. Reading and Writing Files in C++
Prefer RAII file streams over manual FILE* unless needed.
Read lines
#include <fstream>
#include <string>
std::ifstream in("data.txt");
std::string line;
while (std::getline(in, line)) {
std::cout << line << 'n';
}
78. Header Files in C++
Keep headers minimal; avoid unnecessary includes (prefer forward decls).
Header tip
#pragma once or include guards
Declarations in .h
Definitions in .cpp
Inline/templates may live in headers
79. Namespaces in C++
Avoid `using namespace std;` in headers.
Namespace
namespace app {
int version = 1;
}
std::cout << app::version;
80. Preprocessor Directives in C++
Prefer constexpr/templates/inline over complex macros.
Preprocessor tip
#include
#pragma once
#ifndef guards
Avoid heavy macros
81. Standard Template Library (STL) in C++
STL is the heart of idiomatic modern C++.
STL pillars
Containers
Iterators
Algorithms
Function objects / lambdas
82. std::vector in C++
Reserve capacity when size is predictable; prefer push_back/emplace_back.
vector
#include <vector>
std::vector<int> v = {1, 2, 3};
v.push_back(4);
83. std::list in C++
Often slower than vector due to cache locality — measure before choosing.
list tip
Stable node addresses
Good splice
Usually prefer vector/deque unless needed
84. std::deque in C++
Good middle ground for double-ended queues.
deque tip
push_front / push_back fast
Random access supported
Not fully contiguous
85. std::stack in C++
Default underlying container is deque.
stack
#include <stack>
std::stack<int> st;
st.push(1);
int top = st.top();
st.pop();
86. std::queue in C++
front/back + push/pop are the core API.
queue
#include <queue>
std::queue<int> q;
q.push(10);
int x = q.front();
q.pop();
87. std::priority_queue in C++
Default is max-heap; customize comparator for min-heap.
priority_queue
#include <queue>
std::priority_queue<int> pq;
pq.push(3);
pq.push(9);
int best = pq.top();
88. std::set in C++
Lookups/inserts are typically logarithmic.
set
#include <set>
std::set<int> s = {3, 1, 2};
s.insert(2); // still one 2
89. std::multiset in C++
Useful for frequency-like ordered collections.
multiset tip
Allows duplicates
Ordered
count/equal_range useful
90. std::map in C++
operator[] default-constructs missing values — use find/insert carefully.
map
#include <map>
std::map<std::string, int> ages;
ages["Asha"] = 30;
91. std::multimap in C++
Use equal_range to iterate all values for a key.
multimap tip
Duplicate keys allowed
equal_range for groups
No operator[]
92. Iterators in C++
Prefer range-for; use iterators for algorithms and erase patterns.
Iterator
for (auto it = v.begin(); it != v.end(); ++it) {
std::cout << *it << ' ';
}
93. STL Algorithms in C++
Algorithms + iterators = expressive, tested building blocks.
algorithms
#include <algorithm>
std::sort(v.begin(), v.end());
auto it = std::find(v.begin(), v.end(), 42);
94. Lambda Expressions in C++
Capture by value/reference carefully — watch dangling refs.
Lambda
std::sort(v.begin(), v.end(), [](int a, int b) {
return a > b;
});
95. Smart Pointers in C++
Default to unique_ptr; use shared_ptr only for shared ownership.
Smart pointer map
unique_ptr → exclusive ownership
shared_ptr → shared ownership
weak_ptr → non-owning observer
96. std::unique_ptr in C++
Movable, not copyable — perfect for factory returns.
unique_ptr
#include <memory>
auto p = std::make_unique<User>("Asha");
std::cout << p->name() << 'n';
97. std::shared_ptr in C++
Avoid cycles — break with weak_ptr; prefer unique_ptr when possible.
shared_ptr
auto a = std::make_shared<int>(42);
auto b = a; // ref count 2
98. std::weak_ptr in C++
lock() to get a temporary shared_ptr safely.
weak_ptr tip
std::weak_ptr<int> w = a;
if (auto sp = w.lock()) {
std::cout << *sp << 'n';
}
99. Move Semantics in C++
Moved-from objects must remain valid for destruction.
Move tip
std::string a = "hello";
std::string b = std::move(a); // a valid but unspecified
100. Multithreading in C++
Prefer higher-level concurrency tools; avoid data races.
Thread sketch
#include <thread>
std::thread t([] {
std::cout << "hello from threadn";
});
t.join();
101. C++ Modern Features
Modern C++ is about safer defaults and clearer intent.
Modern defaults
auto where clear
range-for
smart pointers
STL algorithms
constexpr / noexcept thoughtfully
102. C++11, C++14, C++17 and C++20
Pick a standard (`-std=c++17` / `c++20`) and use it consistently.
Highlights
C++11: auto, move, lambdas, smart ptrs, threads
C++14: generic lambdas, relaxed constexpr
C++17: optional/variant/string_view, structured bindings
C++20: concepts, ranges, coroutines, jthread
103. Debugging C++ Applications
Compile with `-Wall -Wextra -g` and use ASan/UBSan for memory/UB issues.
Debug toolkit
Warnings as errors (team choice)
-g symbols
gdb/lldb
ASan/UBSan/TSan
Unit tests
104. Memory Management Best Practices in C++
Every ownership path should be obvious — unique by default.
Memory practices
RAII everywhere
unique_ptr default
No naked new in app code
Avoid cycles with shared_ptr
Measure before custom allocators
105. C++ Coding Standards
Consistency beats perfection — automate with clang-format/clang-tidy.
Standards focus
Naming consistency
const-correctness
No raw owning pointers
Clear header hygiene
Automated format/lint
106. Data Structures and Algorithms with C++
Know both library algorithms and how to implement classics for interviews.
DSA tip
Use STL first
Implement classics to learn
Analyze complexity
Test edge cases
107. Searching and Sorting in C++
Write comparators carefully; keep them strict weak orderings.
sort/search
std::sort(v.begin(), v.end());
bool found = std::binary_search(v.begin(), v.end(), key);
108. C++ Interview Questions
Be ready for Rule of Five/Zero, virtual destructors, move semantics, and STL complexity.
Sample Q&A
Q: new vs make_unique?
A: Prefer make_unique for exception-safe exclusive ownership.
Q: Why virtual destructor?
A: Correct destruction via base pointer.
Q: map vs unordered_map?
A: ordered/log n vs hash/avg O(1).
109. C++ Programming Practice
Build tiny tools and refactor toward modern idioms.
Practice set
Student records with vector
Word frequency with map
CLI todo with file I/O
Implement stack/queue
Sort custom structs
110. Real-World C++ Project
Include CMake/Make, README, and sample inputs.
Project ideas
CSV analyzer
Mini key-value store
JSON config tool (with lib)
Multithreaded downloader (careful)
Game logic module / simulator
111. Final Project – Complete C++ Application
Create a polished CLI app (e.g., inventory/student manager): modular headers/sources, RAII, STL containers, exception-safe I/O, optional smart pointers, CMake/Makefile, and README with build/run instructions.
- Design the domain and module layout.
- Implement CRUD + persistence with STL.
- Harden errors and memory safety.
- Document build/run and demo the app.
Final project scope
1. Domain model with classes
2. STL containers for storage
3. File save/load
4. Menu-driven CLI
5. Input validation + error handling
6. RAII / no leaks
7. Modular .h/.cpp design
8. Build system + README
9. Basic tests or demo script
Suggested layout
CMakeLists.txt or Makefile
include/
src/
README.md
data/sample.txt
Conclusion
You now have a full C++ path: core language, object-oriented design, STL mastery, and modern memory-safe idioms. Finish the final C++ application project to turn the lessons into a portfolio-ready program.