Smart Pointers
Smart Pointers
In modern C++, smart pointers manage dynamically allocated memory automatically, preventing memory leaks and dangling pointers. They are defined in the <memory> header.
The Problem with Raw Pointers
void leaky() {
int* p = new int(42);
// if an exception occurs here, memory leaks!
delete p; // easy to forget
}
Smart pointers solve this by automatically freeing memory when the pointer goes out of scope.
std::unique_ptr
A unique_ptr owns its object exclusively — no other pointer can share ownership.
#include <memory>
using namespace std;
unique_ptr<int> p = make_unique<int>(42);
cout << *p << endl; // 42
// Ownership can be transferred:
unique_ptr<int> q = move(p);
// p is now nullptr, q owns the object
Key rules:
- Cannot be copied — only moved
- When it goes out of scope, the object is deleted
- Use
make_unique<T>(args...)to create one
std::shared_ptr
A shared_ptr allows multiple pointers to share ownership. The object is deleted when the last shared_ptr to it is destroyed.
shared_ptr<int> a = make_shared<int>(100);
shared_ptr<int> b = a; // both point to same object
cout << a.use_count() << endl; // 2
cout << *a << endl; // 100
cout << *b << endl; // 100
Key rules:
- Can be copied freely
- Tracks a reference count — how many shared_ptrs point to the object
- Object is deleted when reference count reaches 0
- Use
make_shared<T>(args...)to create one
When to Use Each
| Pointer | Use when... |
|---|---|
unique_ptr | One owner. Default choice for heap objects. |
shared_ptr | Multiple owners need the same object. |
| Raw pointer | Non-owning reference (observer). Never new/delete. |
Best Practices
- Prefer
make_unique/make_sharedovernew - Default to
unique_ptr— upgrade toshared_ptronly if needed - Never use raw
new/deletein modern C++ - Pass smart pointers by reference to avoid unnecessary copies
Your Task
In this exercise, you will implement simplified smart pointer classes to understand how they work internally.
Create a UniquePtr class that wraps an integer value and provides:
- A constructor that takes the value
- A
get()method that returns the value - Demonstrate exclusive ownership
Create a SharedPtr class that wraps an integer value and tracks reference count:
- A constructor that takes the value
- A
get()method that returns the value - A
refCount()method that returns the count
Print the results as shown in the tests.