在 C++ 中,智能指针是管理动态内存的重要工具。下面我将展示 unique_ptr 和 shared_ptr 的空实现(简化版本),这些实现保留了核心概念但移除了标准库的复杂性,适合教学目的。
#include <utility> // for std::swap
template <typename T>
class unique_ptr {
T* ptr = nullptr;
public:
// 构造函数
explicit unique_ptr(T* p = nullptr) : ptr(p) {}
// 禁止拷贝
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
// 移动语义
unique_ptr(unique_ptr&& other) noexcept : ptr(other.release()) {}
unique_ptr& operator=(unique_ptr&& other) noexcept {
reset(other.release());
return *this;
}
// 析构函数
~unique_ptr() {
delete ptr;
}
// 核心功能
T* release() noexcept {
T* p = ptr;
ptr = nullptr;
return p;
}
void reset(T* p = nullptr) noexcept {
delete ptr;
ptr = p;
}
void swap(unique_ptr& other) noexcept {
std::swap(ptr, other.ptr);
}
// 访问器
T* get() const noexcept { return ptr; }
T& operator*() const noexcept { return *ptr; }
T* operator->() const noexcept { return ptr; }
explicit operator bool() const noexcept { return ptr != nullptr; }
};template <typename T>
class shared_ptr {
T* ptr = nullptr;
int* count = nullptr;
void release() {
if (count && --(*count) == 0) {
delete ptr;
delete count;
}
ptr = nullptr;
count = nullptr;
}
public:
// 构造函数
explicit shared_ptr(T* p = nullptr) : ptr(p), count(p ? new int(1) : nullptr) {}
// 拷贝语义
shared_ptr(const shared_ptr& other) : ptr(other.ptr), count(other.count) {
if (count) ++(*count);
}
shared_ptr& operator=(const shared_ptr& other) {
if (this != &other) {
release();
ptr = other.ptr;
count = other.count;
if (count) ++(*count);
}
return *this;
}
// 移动语义
shared_ptr(shared_ptr&& other) noexcept : ptr(other.ptr), count(other.count) {
other.ptr = nullptr;
other.count = nullptr;
}
shared_ptr& operator=(shared_ptr&& other) noexcept {
if (this != &other) {
release();
ptr = other.ptr;
count = other.count;
other.ptr = nullptr;
other.count = nullptr;
}
return *this;
}
// 析构函数
~shared_ptr() {
release();
}
// 核心功能
void reset(T* p = nullptr) {
release();
ptr = p;
count = p ? new int(1) : nullptr;
}
void swap(shared_ptr& other) noexcept {
std::swap(ptr, other.ptr);
std::swap(count, other.count);
}
// 访问器
T* get() const noexcept { return ptr; }
T& operator*() const noexcept { return *ptr; }
T* operator->() const noexcept { return ptr; }
explicit operator bool() const noexcept { return ptr != nullptr; }
int use_count() const noexcept { return count ? *count : 0; }
};特性 | 空实现 | 标准库实现 |
|---|---|---|
基础内存管理 | ✓ | ✓ |
移动语义 | ✓ | ✓ |
引用计数 | ✓ (shared_ptr) | ✓ |
自定义删除器 | ✗ | ✓ |
数组支持 | ✗ | ✓ (unique_ptr<T[]>) |
原子操作 | ✗ | ✓ (shared_ptr) |
类型转换 | ✗ | ✓ (const_pointer_cast等) |
weak_ptr支持 | ✗ | ✓ |
make_shared/make_unique | ✗ | ✓ |
异常安全 | 基础 | 完整 |
性能优化 | ✗ | ✓ (如控制块合并) |
class Resource {
public:
Resource() { std::cout << "Resource created\n"; }
~Resource() { std::cout << "Resource destroyed\n"; }
void use() { std::cout << "Using resource\n"; }
};
int main() {
// unique_ptr 示例
{
unique_ptr<Resource> uptr(new Resource());
uptr->use();
// 移动所有权
unique_ptr<Resource> uptr2 = std::move(uptr);
if (!uptr) {
std::cout << "uptr is now empty\n";
}
} // uptr2 超出作用域,资源释放
// shared_ptr 示例
{
shared_ptr<Resource> sptr1(new Resource());
std::cout << "Use count: " << sptr1.use_count() << "\n"; // 1
{
shared_ptr<Resource> sptr2 = sptr1;
std::cout << "Use count: " << sptr1.use_count() << "\n"; // 2
sptr2->use();
}
std::cout << "Use count: " << sptr1.use_count() << "\n"; // 1
} // sptr1 超出作用域,资源释放
}Resource created
Using resource
uptr is now empty
Resource destroyed
Resource created
Use count: 1
Use count: 2
Using resource
Use count: 1
Resource destroyeddelete 操作符unique_ptr 支持 unique_ptr<T[]>shared_ptr 的引用计数是原子操作make_shared 可以合并控制块和对象内存这些空实现保留了智能指针的核心概念(所有权语义、自动内存管理),但移除了标准库中的高级特性,适合用于理解智能指针的基本原理。在实际项目中,应始终使用标准库的智能指针实现。