Modern C++ Smart Pointers: A Learn-by-Doing Guide

Introduction

Manual memory management in C++ is error-prone and can lead to memory leaks, dangling pointers, and undefined behavior. C++11 introduced smart pointers in the <memory> header to solve this elegantly using RAII.

1. Types of Smart Pointers in C++11

1.1 std::unique_ptr

Syntax and Usage:

#include <memory>
#include <iostream>

struct MyClass {
    MyClass() { std::cout << "Constructed\\n"; }
    ~MyClass() { std::cout << "Destroyed\\n"; }
    void greet() { std::cout << "Hello from unique_ptr!\\n"; }
};

int main() {
    std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>();
    ptr1->greet();

    // Transfer ownership
    std::unique_ptr<MyClass> ptr2 = std::move(ptr1);

    // Resetting
    ptr2.reset(); // deletes object
}

1.2 std::shared_ptr

Syntax and Usage:

#include <memory>
#include <iostream>

struct MyClass {
    MyClass() { std::cout << "Constructed\\n"; }
    ~MyClass() { std::cout << "Destroyed\\n"; }
};

int main() {
    std::shared_ptr<MyClass> sp1 = std::make_shared<MyClass>();
    std::shared_ptr<MyClass> sp2 = sp1; // shared ownership

    std::cout << "Use count: " << sp1.use_count() << "\\n"; // 2

    sp1.reset(); // sp2 still holds ownership
}

1.3 std::weak_ptr

Syntax and Usage:

#include <memory>
#include <iostream>

struct MyClass {
    void sayHi() { std::cout << "Hi from weak_ptr!\\n"; }
};

int main() {
    std::shared_ptr<MyClass> sp = std::make_shared<MyClass>();
    std::weak_ptr<MyClass> wp = sp;

    if (auto spt = wp.lock()) { // Check if resource is still alive
        spt->sayHi();
    }
}