A smart pointer is a pointer-like C++ object that manages a dynamically allocated resource according to an ownership policy. Its RAII behavior releases resources when the pointer leaves scope, including during exception handling, reducing manual cleanup and memory leaks. section 2.0 section 10.4
Choose the ownership model deliberately:
- Use std::unique_ptr for exclusive ownership. It is comparatively inexpensive, cannot be copied, and can transfer ownership with std::move. section 10.6 section 2.9
- Use std::shared_ptr only when ownership is genuinely shared. Reference counting deletes the resource when the count reaches zero, but adds storage and runtime cost. section 2.9
- Watch for cycles created by shared pointers; a weak pointer observes the resource without owning it and can break the cycle. section 2.9
- For older code that cannot use modern C++, Boost offers exclusive scoped_ptr and shared_ptr alternatives; avoid auto_ptr, which was deprecated and removed. section 10.6
Replacing manual cleanup
Raw Student pointers require separate checks and deletes in an exception handler. Replacing them with managed objects makes cleanup automatic: std::unique_ptr<int> ptr1 = std::make_unique<int>(42); std::unique_ptr<int> ptr2 = std::move(ptr1); For genuinely shared nodes, std::shared_ptr and std::make_shared can replace a manually deleted deque structure, but linked structures must avoid ownership cycles. section 10.6 section 2.9
Listing 2.18 A deque using shared pointers
class Node {
public:
Node(int value) : data(value) {}
int data;
std::shared_ptr<Node> prev; #1
std::shared_ptr<Node> next; #2
};
class Deque {
private:
std::shared_ptr<Node> front;
std::shared_ptr<Node> back;
public:
Deque() : front(nullptr), back(nullptr) {} #3
void push_front(int value) {
std::shared_ptr<Node> newNode = std::make_shared<Node>(value);
if (front == nullptr)
front = back = newNode;
else {
newNode->next = front;
front->prev = newNode;
front = newNode;
}
}
void push_back(int value) {
std::shared_ptr<Node> newNode = std::make_shared<Node>(value);
if (back == nullptr)
front = back = newNode;
else {
newNode->prev = back;
back->next = newNode;
back = newNode;
}
}
void pop_front() {
if (front != nullptr) {
front = front->next;
if (front != nullptr)
front->prev = nullptr;
else
back = nullptr;
} #B
}
void pop_back() {
if (back != nullptr) {
back = back->prev;
if (back != nullptr)
back->next = nullptr;
else
front = nullptr;
} #4
}
};
int main() {
Deque deque;
deque.push_front(3);
deque.pop_front();
return 0;
}
Shows a deque whose nodes and links use shared pointers, including default nullptr initialization and make_shared construction. section 2.9




