A single-header C++23 library that implements three fundamental smart pointers:
UniquePointer<T>
– exclusive ownershipSharedPointer<T>
– shared ownership with reference countingWeakPointer<T>
– non-owning reference to avoid cycles
This project is a learning-oriented reimplementation of std::unique_ptr
, std::shared_ptr
, and std::weak_ptr
.
It’s header-only: just drop custom.hpp
into your project and start using modern memory management without leaks.
-
UniquePointer
- ✅ Exclusive ownership of dynamically allocated objects
- ✅ Move-only (cannot be copied)
- ✅ Automatic deletion when out of scope
- ✅ Supports arrays via
MakeUniqueArray
-
SharedPointer
- ✅ Reference-counted ownership
- ✅ Control block manages strong/weak counts
- ✅ Copyable and assignable
- ✅ Custom deleter support
- ✅ Aliasing constructor
-
WeakPointer
- ✅ Observes
SharedPointer
without extending lifetime - ✅ Prevents cyclic references
- ✅
lock()
converts to aSharedPointer
safely
- ✅ Observes
/your-repo
├── custom.hpp # The single header with all smart pointer implementations
├── README.md # This file
└── examples.cpp # (optional) usage examples
#include "custom.hpp"
#include <iostream>
int main() {
UniquePointer<int> ptr = MakeUnique<int>(42);
std::cout << *ptr << "\n"; // prints 42
auto arr = MakeUniqueArray<int[]>(5);
for (int i = 0; i < 5; i++) arr[i] = i * 10;
}
#include "custom.hpp"
#include <iostream>
struct Node {
int value;
SharedPointer<Node> next;
WeakPointer<Node> prev; // avoid cyclic ownership
Node(int v) : value(v) {}
};
int main() {
auto a = MakeShared<Node>(1);
auto b = MakeShared<Node>(2);
a->next = b;
b->prev = a; // weak pointer prevents cycle
std::cout << a->next->value << "\n"; // prints 2
}
#include "custom.hpp"
#include <iostream>
struct Wrapper {
int x;
Wrapper(int v) : x(v) {}
};
int main() {
auto sp = MakeShared<Wrapper>(42);
SharedPointer<int> alias(sp, &sp->x); // shares ownership, but points to inner int
std::cout << *alias << "\n"; // prints 42
}
- Stores reference counts (
strong_count
,weak_count
) - Handles object lifetime and deallocation
- Holds only the raw pointer
- Holds pointer + pointer to control block
- Increments/decrements counts on copy/move
- Points to control block but doesn’t affect strong count
lock()
creates aSharedPointer
if object still exists
Feature | UniquePointer | SharedPointer | WeakPointer |
---|---|---|---|
Exclusive ownership | ✅ | ❌ | ❌ |
Shared ownership | ❌ | ✅ | ❌ |
Reference counting | ❌ | ✅ | ✅ (weak only) |
Prevent cycles | ❌ | ❌ | ✅ |
Custom deleter | ✅ | ✅ | ❌ |
- ❌ Educational project – not production-optimized
- ❌ Lacks some advanced features (e.g., allocator support)
- ⚡ Intrusive pointer support
- 🔐 Debug mode for memory leak detection
MIT License – free to use, modify, and distribute.
Built for learning, exploration, and modern C++ practice.