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
}
}