Sobes.tech
Senior

How to implement a smart pointer for one or multiple objects?

sobes.tech AI

Answer from AI

For a single object: unique_ptr or shared_ptr. For multiple objects: shared_ptr (ownership) or weak_ptr (observation without participation in lifetime management).

#include <memory>
#include <vector>

// Example class of object
class MyObject {
public:
    MyObject() { /* Constructor */ }
    ~MyObject() { /* Destructor */ }
};

// For a single object: unique_ptr (exclusive ownership)
void single_unique_ptr() {
    std::unique_ptr<MyObject> ptr = std::make_unique<MyObject>();
    // Object will be automatically deleted when leaving scope
}

// For a single object: shared_ptr (shared ownership)
void single_shared_ptr() {
    std::shared_ptr<MyObject> ptr = std::make_shared<MyObject>();
    // Reference count increases
    std::shared_ptr<MyObject> another_ptr = ptr;
    // Object will be deleted when the last shared_ptr referencing it is destroyed
}

// For multiple objects: vector with shared_ptr
void multiple_shared_ptr() {
    std::vector<std::shared_ptr<MyObject>> objects;
    objects.push_back(std::make_shared<MyObject>());
    objects.push_back(std::make_shared<MyObject>());
    // Each object is managed by its shared_ptr in the vector
    // Objects will be deleted after their shared_ptrs are destroyed
}

// For multiple objects: vector with unique_ptr
void multiple_unique_ptr() {
    std::vector<std::unique_ptr<MyObject>> objects;
    objects.push_back(std::make_unique<MyObject>());
    objects.push_back(std::make_unique<MyObject>());
    // The vector owns the unique pointers
    // Objects will be deleted when the vector goes out of scope

    // Note: unique_ptr cannot be copied, only moved
    std::unique_ptr<MyObject> moved_ptr = std::move(objects[0]);
}

Comparison of unique_ptr and shared_ptr:

Feature std::unique_ptr std::shared_ptr
Ownership Exclusive Shared (reference counting)
Copying No (only move) Yes
Performance Slightly higher (no reference count overhead) Slightly lower (reference count management)
Cyclic references Not protected Can lead to memory leaks (requires weak_ptr)

std::weak_ptr is used to observe an object managed by shared_ptr without increasing the reference count, preventing cyclic reference issues.

#include <memory>

class Node {
public:
    std::shared_ptr<Node> next;
    std::weak_ptr<Node> previous; // Using weak_ptr to avoid cyclic reference

    Node() = default;
    ~Node() { /* Destructor */ }
};

void weak_ptr_example() {
    std::shared_ptr<Node> node1 = std::make_shared<Node>();
    std::shared_ptr<Node> node2 = std::make_shared<Node>();

    node1->next = node2;
    node2->previous = node1; // Using weak_ptr

    // Can obtain shared_ptr from weak_ptr to access the object
    if (std::shared_ptr<Node> locked_node = node2->previous.lock()) {
        // If the object is still alive
        // ... work with locked_node
    } else {
        // Object has been deleted
    }
}