本文最后更新于49 天前,其中的信息可能已经过时,如有错误请留言
#include <iostream>
#include <atomic>
#include <utility>
template<typename T>
class SharedPtr {
private:
T* ptr;
std::atomic<size_t>* ref_count;
void release() {
if (ref_count) {
if (ref_count->fetch_sub(1) == 1) {
delete ptr;
delete ref_count;
std::cout << "Resource destroyed." << std::endl;
}
}
}
public:
explicit SharedPtr(T* p = nullptr):ptr(p), ref_count(p ? new std::atomic<size_t>(1) : nullptr) {}
SharedPtr(const SharedPtr& other):ptr(other.ptr), ref_count(other.ref_count) {
if (ref_count) {
ref_count->fetch_add(1);
}
}
SharedPtr& operator=(const SharedPtr& other) {
if (this != &other) {
release();
ptr = other.ptr;
ref_count = other.ref_count;
if (ref_count) {
ref_count->fetch_add(1);
}
}
return *this;
}
~SharedPtr() { release(); }
SharedPtr(SharedPtr&& other) noexcept : ptr(other.ptr), ref_count(other.ref_count) {
other.ptr = nullptr;
other.ref_count = nullptr;
}
SharedPtr& operator=(SharedPtr&& other) noexcept {
if (this != &other) {
release();
ptr = other.ptr;
ref_count = other.ref_count;
other.ptr = nullptr;
other.ref_count = nullptr;
}
return *this;
}
T& operator*() const {
return *ptr;
}
T* operator->() const {
return ptr;
}
T* get() const {
return ptr;
}
size_t use_count() const {
return ref_count ? ref_count->load() : 0;
}
explicit operator bool() const {
return ptr != nullptr;
}
};
// --- 测试代码 ---
class Test {
public:
int content;
Test(int v) : content(v) { std::cout << "Test Ctor: " << content << std::endl; }
~Test() { std::cout << "Test Dtor" << std::endl; }
};
int main() {
// 1. 普通构造
SharedPtr<Test> sp1(new Test(100));
std::cout << "sp1 use_count: " << sp1.use_count() << std::endl; // 1
{
// 2. 拷贝构造
SharedPtr<Test> sp2 = sp1;
std::cout << "sp1 use_count: " << sp1.use_count() << std::endl; // 2
std::cout << "sp2 content: " << sp2->content << std::endl;
} // sp2 离开作用域,计数 -1
std::cout << "sp1 use_count back to: " << sp1.use_count() << std::endl; // 1
// 3. 移动语义
SharedPtr<Test> sp3(new Test(200));
SharedPtr<Test> sp4 = std::move(sp3); // sp3 变为空
std::cout << "sp3 empty? " << (sp3.get() == nullptr) << std::endl; // 1 (true)
std::cout << "sp4 use_count: " << sp4.use_count() << std::endl; // 1
return 0;
}


