Modern C++

Smart Pointers

Use modern C++ smart pointers to manage memory safely and automatically.

The Problem with Raw Pointers

Manual memory management with new and delete is error-prone:

  • Forget to delete → memory leak
  • Delete twice → undefined behavior
  • Use after delete → use-after-free bug

Smart Pointers (C++11)

Smart pointers automatically manage memory using RAII (Resource Acquisition Is Initialization):

  • unique_ptr: Sole ownership, automatically deleted when out of scope
  • shared_ptr: Shared ownership, deleted when last owner goes out of scope
  • weak_ptr: Non-owning reference to a shared_ptr (breaks circular references)

The Rule: Prefer Smart Pointers

In modern C++, you should rarely use raw new/delete. Use smart pointers instead.

Example

cpp
#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class Resource {
    string name;
public:
    Resource(const string& n) : name(n) {
        cout << "Acquired: " << name << endl;
    }
    ~Resource() {
        cout << "Released: " << name << endl;
    }
    void use() { cout << "Using: " << name << endl; }
};

void demonstrateUniquePtr() {
    // unique_ptr - sole ownership
    unique_ptr<Resource> res = make_unique<Resource>("FileHandle");
    res->use();

    // Transfer ownership with move
    unique_ptr<Resource> res2 = move(res);
    // res is now null
    if (!res) cout << "res is empty after move" << endl;
    res2->use();
    // Automatically deleted when res2 goes out of scope
}

void demonstrateSharedPtr() {
    shared_ptr<Resource> r1 = make_shared<Resource>("SharedDB");
    cout << "Count: " << r1.use_count() << endl;  // 1
    {
        shared_ptr<Resource> r2 = r1;  // shared ownership
        cout << "Count: " << r1.use_count() << endl;  // 2
        r2->use();
    }  // r2 destroyed, count goes to 1
    cout << "Count: " << r1.use_count() << endl;  // 1
}  // r1 destroyed, Resource released

int main() {
    cout << "--- unique_ptr ---" << endl;
    demonstrateUniquePtr();

    cout << "--- shared_ptr ---" << endl;
    demonstrateSharedPtr();

    // unique_ptr in containers
    vector<unique_ptr<Resource>> resources;
    resources.push_back(make_unique<Resource>("Res1"));
    resources.push_back(make_unique<Resource>("Res2"));

    for (auto& r : resources) r->use();
    // All automatically freed when vector is destroyed

    return 0;
}
Try it yourself — CPP