Skip to content
C++ Programming Language Guide — Object-Oriented and Modern C++

C++ Programming Language Guide — Object-Oriented and Modern C++

DodaTech Updated Jun 7, 2026 7 min read

C++ is a multi-paradigm systems programming language that extends C with object-oriented, generic, and functional features, giving you high-level abstractions with zero-cost performance.

What You’ll Learn

  • Classes, inheritance, and polymorphism
  • Templates for generic programming
  • STL containers: vectors, maps, and algorithms
  • RAII and smart pointers for automatic resource management
  • Modern C++ features from C++11 through C++20

Why It Matters

C++ drives performance-critical applications where speed matters most — game engines (Unreal), web browsers (Chrome’s Blink, Firefox’s Quantum), database systems, high-frequency trading, and DodaZIP’s compression engine. Unlike C, C++ provides RAII and smart pointers that prevent memory leaks while maintaining the same raw performance. Modern C++ (C++11 and later) is almost a different language — safer, cleaner, and more expressive than classic C++.

Learning Path

    flowchart LR
  A[C++ Basics<br/>You are here] --> B[Classes & OOP]
  B --> C[Templates & STL]
  C --> D[RAII & Smart Pointers]
  D --> E[Build a Game Engine Component]
  

Classes and Object-Oriented Programming

C++ classes encapsulate data and behavior. Access specifiers (public, private, protected) control visibility.

#include <iostream>
#include <string>

class Animal {
protected:
    std::string name;

public:
    Animal(const std::string& n) : name(n) {}

    virtual void speak() const {
        std::cout << name << " makes a sound" << std::endl;
    }

    virtual ~Animal() = default;
};

class Dog : public Animal {
public:
    Dog(const std::string& n) : Animal(n) {}

    void speak() const override {
        std::cout << name << " says Woof!" << std::endl;
    }
};

int main() {
    Dog dog("Rex");
    dog.speak();  // Rex says Woof!

    Animal* animal = new Dog("Buddy");
    animal->speak();  // Buddy says Woof!
    delete animal;

    return 0;
}

Templates

Templates enable generic programming — writing code that works with any type.

#include <iostream>
#include <string>

template <typename T>
T maximum(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    std::cout << maximum(3, 7) << std::endl;           // 7
    std::cout << maximum(3.14, 2.71) << std::endl;     // 3.14
    std::cout << maximum(std::string("apple"),
                         std::string("orange")) << std::endl;  // orange

    return 0;
}

STL Containers

The Standard Template Library provides efficient, type-safe data structures.

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>

int main() {
    // Vector — dynamic array
    std::vector<int> numbers = {4, 2, 5, 1, 3};
    std::sort(numbers.begin(), numbers.end());

    for (int n : numbers) {
        std::cout << n << " ";
    }
    std::cout << std::endl;
    // 1 2 3 4 5

    // Map — key-value store (sorted by key)
    std::map<std::string, int> scores;
    scores["Alice"] = 95;
    scores["Bob"] = 87;
    scores["Charlie"] = 92;

    for (const auto& [name, score] : scores) {
        std::cout << name << ": " << score << std::endl;
    }
    // Alice: 95
    // Bob: 87
    // Charlie: 92

    return 0;
}

RAII and Smart Pointers

RAII (Resource Acquisition Is Initialization) ties resource lifetime to object lifetime. Smart pointers automate memory management.

#include <iostream>
#include <memory>

class Resource {
public:
    Resource() { std::cout << "Resource acquired" << std::endl; }
    ~Resource() { std::cout << "Resource released" << std::endl; }
    void work() { std::cout << "Working..." << std::endl; }
};

int main() {
    // unique_ptr — exclusive ownership
    std::unique_ptr<Resource> ptr = std::make_unique<Resource>();
    ptr->work();

    // shared_ptr — shared ownership with reference counting
    std::shared_ptr<Resource> shared1 = std::make_shared<Resource>();
    {
        std::shared_ptr<Resource> shared2 = shared1;
        std::cout << "Reference count: " << shared1.use_count() << std::endl;
        // Reference count: 2
    }
    std::cout << "Reference count: " << shared1.use_count() << std::endl;
    // Reference count: 1

    // Resources are automatically freed when pointers go out of scope
    return 0;
}

Output:

Resource acquired
Working...
Resource acquired
Reference count: 2
Reference count: 1
Resource released
Resource released

Modern C++ Features

C++11 through C++20 introduced powerful features:

#include <iostream>
#include <vector>
#include <optional>

// C++11: auto, range-based for, lambdas
// C++14: generic lambdas
// C++17: structured bindings, optional
// C++20: concepts, ranges

// C++20 concept
template <typename T>
concept Numeric = std::is_arithmetic_v<T>;

auto process(Numeric auto value) {
    return value * 2;
}

int main() {
    // Lambda with auto parameters (C++14)
    auto multiply = [](auto a, auto b) { return a * b; };
    std::cout << multiply(3, 4) << std::endl;        // 12
    std::cout << multiply(2.5, 3.0) << std::endl;    // 7.5

    // std::optional (C++17)
    std::optional<int> maybe_value = 42;
    if (maybe_value) {
        std::cout << "Value: " << *maybe_value << std::endl;
        // Value: 42
    }

    // Structured bindings (C++17)
    std::vector<std::pair<int, std::string>> pairs = {{1, "one"}, {2, "two"}};
    for (const auto& [num, word] : pairs) {
        std::cout << num << " = " << word << std::endl;
    }
    // 1 = one
    // 2 = two

    std::cout << process(10) << std::endl;   // 20
    std::cout << process(3.14) << std::endl; // 6.28

    return 0;
}

Common Mistakes

1. Forgetting virtual destructors

If a base class has virtual functions, it must have a virtual destructor. Otherwise, deleting a derived object through a base pointer causes undefined behavior.

2. Using raw new/delete instead of smart pointers

Prefer std::make_unique and std::make_shared. Raw new/delete has no place in modern C++ except in low-level library code.

3. Passing large objects by value

Pass const T& or T&& instead. Copying large objects like vectors or strings on every function call kills performance.

4. Iterator invalidation

Modifying a vector (inserting/erasing) invalidates all iterators pointing to it. Re-obtain iterators after modifications.

5. Not initializing member variables

class Point {
    int x, y;  // uninitialized — contains garbage
};

Always initialize in the member initializer list or with default member initializers (C++11).

6. Using #include <bits/stdc++.h>

This is a GCC internal header that slows compilation. Include only the specific headers you need.

Practice Questions

  1. What is RAII? Resource Acquisition Is Initialization — resource lifetime is tied to object lifetime. When an object goes out of scope, its destructor releases the resource automatically.

  2. What’s the difference between vector and list? vector is a contiguous dynamic array — fast random access, slow insert/delete in the middle. list is a doubly-linked list — slow random access, fast insert/delete anywhere.

  3. What does override do? It tells the compiler the function is meant to override a virtual function in a base class. The compiler catches mistakes like mismatched signatures.

  4. When would you use map vs unordered_map? map is sorted (red-black tree), O(log n). unordered_map is hash-based, average O(1). Use map when you need ordered iteration; use unordered_map for raw speed.

  5. What is the Rule of Five? If a class defines a custom destructor, copy constructor, copy assignment, move constructor, or move assignment, it usually needs all five.

Challenge: Write a C++ program that reads a large text file, counts word frequencies using a std::unordered_map, sorts by frequency, and prints the top 20 words.

Mini Project — Simple CSV Parser

Build a minimal CSV parser using modern C++ features.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>

class CSVRow {
public:
    std::vector<std::string> columns;

    std::string operator[](size_t i) const {
        return i < columns.size() ? columns[i] : "";
    }
};

class CSVParser {
    std::ifstream file;

public:
    CSVParser(const std::string& filename) : file(filename) {}

    bool read_row(CSVRow& row) {
        std::string line;
        if (!std::getline(file, line)) return false;

        row.columns.clear();
        std::stringstream ss(line);
        std::string cell;

        while (std::getline(ss, cell, ',')) {
            row.columns.push_back(cell);
        }
        return true;
    }
};

int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " <file.csv>" << std::endl;
        return 1;
    }

    CSVParser parser(argv[1]);
    CSVRow row;
    int count = 0;

    while (parser.read_row(row)) {
        std::cout << "Row " << ++count << ": ";
        for (const auto& col : row.columns) {
            std::cout << "[" << col << "] ";
        }
        std::cout << std::endl;
    }

    return 0;
}

FAQ

What is the difference between C and C++?
C++ is a superset of C that adds classes, templates, exceptions, operator overloading, and the STL. C is procedural; C++ supports multiple paradigms.
Do I need to learn C before C++?
No. Modern C++ avoids most C compatibility patterns. Learning C++ directly with std::vector, std::string, and smart pointers gives you clean, safe code from day one.
What compiler should I use?
GCC (g++) and Clang (clang++) are the most popular. Both support C++20. MSVC is the standard on Windows. Build with -Wall -Wextra -std=c++20.
What are the most important modern C++ features?
auto, smart pointers, range-based for loops, lambdas, constexpr, move semantics, std::optional, std::variant, structured bindings, and concepts.
Is C++ still used for new projects?
Yes — game engines, browsers, databases, embedded systems, and high-frequency trading all use modern C++ for new development. The job market for C++ remains strong.
How do C++ exceptions compare to Bash error handling?
C++ exceptions unwind the stack with destructors called automatically, unlike Bash’s manual exit code checking. Both serve the same purpose — handling unexpected conditions — but C++’s mechanism is more structured.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro