C++ Programming Tutorial

Learn modern C++ step-by-step — from basics to advanced features like templates, STL, and smart pointers. Clear explanations with practical, runnable examples.

C++ Classes and Objects

A class is a user-defined type that bundles data (member variables) and behavior (member functions) together. Objects are instances of a class. Classes are the foundation of object-oriented programming in C++.

Defining a Class

class_basics.cpp
#include <iostream>
#include <string>

class Dog {
private:  // only accessible inside the class
    std::string name;
    int age;

public:  // accessible from outside
    // Constructor — initializes the object
    Dog(std::string n, int a) : name(std::move(n)), age(a) {}

    // Member functions (methods)
    void bark() const {
        std::cout << name << " says Woof!
";
    }

    std::string get_name() const { return name; }
    int get_age() const { return age; }

    void set_age(int new_age) {
        if (new_age >= 0) age = new_age;
    }
};

int main() {
    Dog rex("Rex", 3);
    rex.bark();  // Rex says Woof!
    std::cout << rex.get_name() << " is " << rex.get_age() << " years old
";

    rex.set_age(4);
    // rex.name = "X";  // ERROR: name is private

    return 0;
}

Constructors and Destructors

constructors.cpp
#include <iostream>
#include <string>

class Connection {
    std::string host;
    int port;
    bool connected;

public:
    // Default constructor
    Connection() : host("localhost"), port(8080), connected(false) {
        std::cout << "Default connection created
";
    }

    // Parameterized constructor
    Connection(std::string h, int p)
        : host(std::move(h)), port(p), connected(false) {
        std::cout << "Connection to " << host << ":" << port << "
";
    }

    // Destructor — called when object goes out of scope
    ~Connection() {
        if (connected) disconnect();
        std::cout << "Connection destroyed
";
    }

    void connect() { connected = true; }
    void disconnect() { connected = false; }
};

int main() {
    Connection c1;                        // calls default constructor
    Connection c2("api.example.com", 443); // calls parameterized
    c2.connect();
    return 0;
}  // destructors called automatically here

Access Specifiers

SpecifierInside classDerived classOutsideUse case
privateYesNoNoInternal state (default for class)
protectedYesYesNoState accessible to subclasses
publicYesYesYesPublic API (methods, constructors)

Operator Overloading

operators.cpp
#include <iostream>

class Vector2D {
public:
    double x, y;

    Vector2D(double x, double y) : x(x), y(y) {}

    // Overload + operator
    Vector2D operator+(const Vector2D& other) const {
        return {x + other.x, y + other.y};
    }

    // Overload == operator
    bool operator==(const Vector2D& other) const {
        return x == other.x && y == other.y;
    }

    // Overload << for printing
    friend std::ostream& operator<<(std::ostream& os, const Vector2D& v) {
        return os << "(" << v.x << ", " << v.y << ")";
    }
};

int main() {
    Vector2D a(1, 2), b(3, 4);
    Vector2D c = a + b;
    std::cout << c << "
";  // (4, 6)
    std::cout << std::boolalpha << (a == b) << "
";  // false
    return 0;
}

The Rule of Five

If your class manages a resource (heap memory, file handle, socket), you should define or delete these five special members:

  • Destructor — releases the resource
  • Copy constructor — deep-copies the resource
  • Copy assignment operator — cleans up old, copies new
  • Move constructor — transfers ownership (C++11)
  • Move assignment operator — cleans up old, transfers new (C++11)

For most classes, prefer using RAII wrappers (std::unique_ptr, std::string, std::vector) so the compiler-generated defaults work correctly.

Best Practices

  • Keep data private and expose it through public methods (encapsulation).
  • Use the member initializer list in constructors for efficiency.
  • Mark methods const when they do not modify the object state.
  • Prefer = default and = delete for special members over empty implementations.
  • Use struct for simple data aggregates; class for types with invariants.

Keep Practicing

Use the online compiler to run every example and experiment with modifications. The best way to learn C++ is by writing code — even small programs build strong foundations.