What is C++?
C++ is a general-purpose programming language created as an extension of C. It supports procedural, object-oriented, and generic programming, offering high performance with low-level memory control.
Performance
Zero-overhead abstractions and direct hardware access. Compile to native code for maximum speed.
Multi-Paradigm
Procedural, object-oriented, functional, and generic programming. Use what fits your problem.
RAII
Resource Acquisition Is Initialization. Automatic resource management tied to object lifetime.
Rich Ecosystem
Massive standard library, countless third-party libraries, and decades of tools and frameworks.
Basics
Hello World
#include <iostream> int main() { std::cout << "Hello, World!" << std::endl; return 0; }
Variables
// Basic types int x = 42; double pi = 3.14159; bool flag = true; char letter = 'A'; // Auto type deduction (C++11) auto y = 42; // int auto z = 3.14; // double // Constants const int MAX = 100; constexpr int SIZE = 256; // compile-time constant // Initialization (C++11) int a{5}; // uniform initialization int b = {5}; int c(5); // constructor syntax
Functions
// Basic function int add(int a, int b) { return a + b; } // Function overloading double add(double a, double b) { return a + b; } // Default parameters void greet(std::string name = "World") { std::cout << "Hello, " << name << "!\n"; } // Inline functions inline int square(int x) { return x * x; } // Lambda expressions (C++11) auto multiply = [](int a, int b) { return a * b; }; int result = multiply(3, 4);
Control Flow
// if-else if (x > 0) { // positive } else if (x < 0) { // negative } else { // zero } // switch switch (value) { case 1: // do something break; case 2: // do something else break; default: // default case } // for loop for (int i = 0; i < 10; i++) { std::cout << i << "\n"; } // range-based for (C++11) std::vector<int> nums = {1, 2, 3, 4, 5}; for (auto num : nums) { std::cout << num << "\n"; } // while while (condition) { // loop body } // do-while do { // loop body } while (condition);
Types
Primitive Types
| Type | Size | Range/Notes |
|---|---|---|
bool |
1 byte | true or false |
char |
1 byte | -128 to 127 or 0 to 255 |
short |
2 bytes | -32,768 to 32,767 |
int |
4 bytes | ~-2 billion to 2 billion |
long |
4-8 bytes | Platform dependent |
long long |
8 bytes | Very large integers |
float |
4 bytes | Single precision |
double |
8 bytes | Double precision |
Compound Types
// Arrays int arr[5] = {1, 2, 3, 4, 5}; int matrix[3][3]; // 2D array // std::array (C++11) - safer than raw arrays std::array<int, 5> arr2 = {1, 2, 3, 4, 5}; // Structures struct Point { int x; int y; }; Point p = {10, 20}; // Enums enum Color { RED, GREEN, BLUE }; // Enum class (C++11) - type-safe enum class Status { OK, ERROR, PENDING }; Status s = Status::OK;
Strings
#include <string> // C-style strings char str[] = "Hello"; const char* ptr = "World"; // std::string std::string s1 = "Hello"; std::string s2("World"); // String operations std::string full = s1 + ", " + s2; // concatenation size_t len = s1.length(); char first = s1[0]; s1.append("!"); s1.substr(0, 5); // substring s1.find("ell"); // returns position or npos // String view (C++17) - non-owning std::string_view sv = "Hello";
Pointers & References
Pointers
// Pointer basics int x = 42; int* ptr = &x; // pointer to x int value = *ptr; // dereference (get value) // Null pointers int* p1 = nullptr; // C++11 (preferred) int* p2 = NULL; // old style int* p3 = 0; // old style // Pointer arithmetic int arr[] = {1, 2, 3}; int* p = arr; p++; // points to arr[1] int val = *(p + 1); // arr[2] // Const pointers const int* p4 = &x; // pointer to const int int* const p5 = &x; // const pointer to int const int* const p6 = &x; // const pointer to const int
References
// References (must be initialized) int x = 42; int& ref = x; // reference to x ref = 100; // modifies x // Function parameters (pass by reference) void increment(int& n) { n++; } // Const reference (read-only, no copy) void print(const std::string& s) { std::cout << s << "\n"; } // Rvalue references (C++11) - for move semantics void process(std::string&& s) { // s is an rvalue reference }
Dynamic Memory
// new and delete int* p = new int(42); delete p; // Arrays int* arr = new int[10]; delete[] arr; // NOTE: Prefer smart pointers in modern C++!
Memory Management & RAII
RAII (Resource Acquisition Is Initialization) ties resource lifetime to object lifetime. When the object is destroyed, resources are automatically released.
Smart Pointers (C++11)
#include <memory> // unique_ptr - exclusive ownership std::unique_ptr<int> p1 = std::make_unique<int>(42); // std::unique_ptr<int> p2 = p1; // ERROR: cannot copy std::unique_ptr<int> p2 = std::move(p1); // OK: move ownership // shared_ptr - shared ownership (reference counted) std::shared_ptr<int> s1 = std::make_shared<int>(42); std::shared_ptr<int> s2 = s1; // OK: shared ownership std::cout << s1.use_count() << "\n"; // 2 // weak_ptr - non-owning reference (breaks circular refs) std::weak_ptr<int> w1 = s1; if (auto sp = w1.lock()) { // object still exists }
RAII Example
// File handle automatically closed when object destroyed class FileHandler { FILE* file; public: FileHandler(const char* name) { file = fopen(name, "r"); } ~FileHandler() { if (file) fclose(file); } // Delete copy operations FileHandler(const FileHandler&) = delete; FileHandler& operator=(const FileHandler&) = delete; };
Move Semantics (C++11)
class Buffer { int* data; size_t size; public: // Move constructor Buffer(Buffer&& other) noexcept : data(other.data), size(other.size) { other.data = nullptr; other.size = 0; } // Move assignment Buffer& operator=(Buffer&& other) noexcept { if (this != &other) { delete[] data; data = other.data; size = other.size; other.data = nullptr; other.size = 0; } return *this; } };
make_unique and make_shared for exception safety.
Classes & Objects
Basic Class
class Rectangle { private: int width; int height; public: // Constructor Rectangle(int w, int h) : width(w), height(h) {} // Default constructor Rectangle() : width(0), height(0) {} // Member function int area() const { return width * height; } // Getter int getWidth() const { return width; } // Setter void setWidth(int w) { width = w; } }; // Usage Rectangle r1(10, 5); std::cout << r1.area() << "\n"; // 50
Constructor Initialization List
class Person { std::string name; int age; const int id; // must use initialization list public: // Preferred: initialization list Person(std::string n, int a, int i) : name(n), age(a), id(i) {} };
Special Member Functions
class MyClass { public: // Constructor MyClass() { } // Destructor ~MyClass() { } // Copy constructor MyClass(const MyClass& other) { } // Copy assignment MyClass& operator=(const MyClass& other) { return *this; } // Move constructor (C++11) MyClass(MyClass&& other) noexcept { } // Move assignment (C++11) MyClass& operator=(MyClass&& other) noexcept { return *this; } }; // Rule of Five: if you define one, define all or delete them // Or use = default / = delete class Simple { public: Simple() = default; Simple(const Simple&) = delete; // no copying };
Operator Overloading
class Vector2D { double x, y; public: Vector2D(double x, double y) : x(x), y(y) {} // Operator + Vector2D operator+(const Vector2D& other) const { return Vector2D(x + other.x, y + other.y); } // Operator == bool operator==(const Vector2D& other) const { return x == other.x && y == other.y; } // Operator << (friend function) friend std::ostream& operator<<(std::ostream& os, const Vector2D& v) { os << "(" << v.x << ", " << v.y << ")"; return os; } };
Static Members
class Counter { static int count; // shared by all instances public: Counter() { count++; } static int getCount() { return count; } }; // Define static member int Counter::count = 0; // Access without instance int n = Counter::getCount();
Inheritance & Polymorphism
Basic Inheritance
class Animal { protected: std::string name; public: Animal(std::string n) : name(n) {} void eat() { std::cout << name << " is eating\n"; } }; // Derived class class Dog : public Animal { public: Dog(std::string n) : Animal(n) {} void bark() { std::cout << name << " barks!\n"; } }; Dog d("Rex"); d.eat(); // inherited d.bark(); // own method
Virtual Functions & Polymorphism
class Shape { public: // Virtual function virtual double area() const { return 0; } // Virtual destructor (important!) virtual ~Shape() = default; }; class Circle : public Shape { double radius; public: Circle(double r) : radius(r) {} // Override (C++11 keyword) double area() const override { return 3.14159 * radius * radius; } }; // Polymorphism Shape* s = new Circle(5); std::cout << s->area() << "\n"; // calls Circle::area delete s;
Abstract Classes
// Pure virtual function = abstract class class Drawable { public: virtual void draw() const = 0; // pure virtual virtual ~Drawable() = default; }; class Rectangle : public Drawable { public: void draw() const override { std::cout << "Drawing rectangle\n"; } };
Access Specifiers
- public
- Accessible from anywhere
- protected
- Accessible in class and derived classes
- private
- Accessible only within the class
Templates
Templates enable generic programming. Write code once, use with any type.
Function Templates
// Generic function template<typename T> T max(T a, T b) { return (a > b) ? a : b; } // Usage int i = max(3, 7); // T = int double d = max(3.5, 2.1); // T = double // Multiple template parameters template<typename T, typename U> auto add(T a, U b) { return a + b; }
Class Templates
// Generic class template<typename T> class Stack { std::vector<T> elements; public: void push(const T& elem) { elements.push_back(elem); } T pop() { T elem = elements.back(); elements.pop_back(); return elem; } bool empty() const { return elements.empty(); } }; // Usage Stack<int> intStack; Stack<std::string> strStack;
Template Specialization
// Generic template template<typename T> class Storage { T data; public: void print() { std::cout << data << "\n"; } }; // Specialization for bool template<> class Storage<bool> { bool data; public: void print() { std::cout << (data ? "true" : "false") << "\n"; } };
Variadic Templates (C++11)
// Variable number of arguments template<typename... Args> void print(Args... args) { (std::cout << ... << args) << "\n"; // fold expression (C++17) } print(1, " hello ", 3.14, " world");
STL Containers
Sequence Containers
#include <vector> #include <deque> #include <list> #include <array> // vector - dynamic array std::vector<int> v = {1, 2, 3}; v.push_back(4); v.pop_back(); int first = v[0]; int last = v.back(); size_t sz = v.size(); // deque - double-ended queue std::deque<int> dq; dq.push_front(1); dq.push_back(2); dq.pop_front(); // list - doubly linked list std::list<int> lst = {1, 2, 3}; lst.push_front(0); lst.push_back(4); // array - fixed-size array (C++11) std::array<int, 5> arr = {1, 2, 3, 4, 5};
Associative Containers
#include <map> #include <set> #include <unordered_map> #include <unordered_set> // map - ordered key-value pairs std::map<std::string, int> ages; ages["Alice"] = 30; ages.insert({"Bob", 25}); if (ages.count("Alice")) { /* exists */ } // set - ordered unique elements std::set<int> s = {3, 1, 4, 1, 5}; // {1, 3, 4, 5} s.insert(2); bool has = s.count(3); // true // unordered_map - hash map (C++11) std::unordered_map<std::string, int> scores; scores["player1"] = 100; // unordered_set - hash set (C++11) std::unordered_set<int> uset = {1, 2, 3};
Container Adaptors
#include <stack> #include <queue> // stack - LIFO std::stack<int> stk; stk.push(1); stk.push(2); int top = stk.top(); stk.pop(); // queue - FIFO std::queue<int> q; q.push(1); int front = q.front(); q.pop(); // priority_queue - heap std::priority_queue<int> pq; pq.push(3); pq.push(1); pq.push(4); int max = pq.top(); // 4
Iterators
// Iterator basics std::vector<int> v = {1, 2, 3, 4, 5}; // Range-based for loop (C++11) for (auto x : v) { std::cout << x << " "; } // Iterator loop for (auto it = v.begin(); it != v.end(); ++it) { std::cout << *it << " "; } // Reverse iterator for (auto it = v.rbegin(); it != v.rend(); ++it) { std::cout << *it << " "; }
Algorithms & Iterators
Common Algorithms
#include <algorithm> #include <numeric> std::vector<int> v = {3, 1, 4, 1, 5, 9}; // Sort std::sort(v.begin(), v.end()); // Sort with custom comparator std::sort(v.begin(), v.end(), std::greater<int>()); // Find auto it = std::find(v.begin(), v.end(), 4); if (it != v.end()) { std::cout << "Found at " << (it - v.begin()); } // Count int count = std::count(v.begin(), v.end(), 1); // Min/Max auto min = std::min_element(v.begin(), v.end()); auto max = std::max_element(v.begin(), v.end()); // Accumulate (sum) int sum = std::accumulate(v.begin(), v.end(), 0); // Reverse std::reverse(v.begin(), v.end()); // Remove duplicates (needs sort first) std::sort(v.begin(), v.end()); v.erase(std::unique(v.begin(), v.end()), v.end());
Transform & Lambda
// Transform with lambda std::vector<int> v = {1, 2, 3, 4, 5}; std::vector<int> result(v.size()); std::transform(v.begin(), v.end(), result.begin(), [](int x) { return x * x; }); // For_each std::for_each(v.begin(), v.end(), [](int x) { std::cout << x << " "; }); // Count_if int evens = std::count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
Ranges (C++20)
#include <ranges> namespace ranges = std::ranges; std::vector<int> v = {1, 2, 3, 4, 5}; // Ranges algorithms ranges::sort(v); auto it = ranges::find(v, 3); // Views (lazy evaluation) auto evens = v | std::views::filter([](int x) { return x % 2 == 0; }); auto squared = evens | std::views::transform([](int x) { return x * x; });
Modern C++ Features
auto & decltype (C++11)
// auto - type deduction auto x = 42; // int auto pi = 3.14; // double auto s = "hello"; // const char* auto v = std::vector<int>{}; // decltype - get type of expression int a = 5; decltype(a) b = 10; // b is int
Range-based for (C++11)
std::vector<int> v = {1, 2, 3}; // By value for (auto x : v) { std::cout << x; } // By reference (modify) for (auto& x : v) { x *= 2; } // By const reference (no copy) for (const auto& x : v) { std::cout << x; }
nullptr (C++11)
// Old way: NULL or 0 int* p1 = NULL; // Modern way: nullptr int* p2 = nullptr; if (p2 == nullptr) { // null pointer }
Structured Bindings (C++17)
// Unpack tuple/pair/struct std::pair<int, std::string> p = {1, "hello"}; auto [id, name] = p; // With map std::map<std::string, int> ages; for (const auto& [key, value] : ages) { std::cout << key << ": " << value; }
Optional (C++17)
#include <optional> // Optional return value std::optional<int> find_value() { if (success) { return 42; } return std::nullopt; } // Usage if (auto val = find_value()) { std::cout << *val; }
std::variant (C++17)
#include <variant> // Type-safe union std::variant<int, double, std::string> v; v = 42; v = 3.14; v = "hello"; // Get value if (auto p = std::get_if<std::string>(&v)) { std::cout << *p; }
Concepts (C++20)
// Define concept template<typename T> concept Numeric = std::is_arithmetic_v<T>; // Use concept template<Numeric T> T add(T a, T b) { return a + b; }
if/switch with initializer (C++17)
// if with initializer if (auto it = m.find(key); it != m.end()) { // use it } // switch with initializer switch (auto val = getValue(); val) { case 1: break; default: break; }