留个坑,回头在填。
#include输出#include #include #include template class shared_ptr { friend class shared_ptr; public: shared_ptr(T* ptr = nullptr) : m_ref(nullptr), m_obj(ptr) { std::cout << "构造函数" << std::endl; if(ptr) { m_ref = new size_t; *m_ref = 1; } } ~shared_ptr() noexcept { std::cout << "析构函数" << std::endl; if(m_ref) { --(*m_ref); } clearMem(); } shared_ptr(const shared_ptr & other) { std::cout << "拷贝构造函数" << std::endl; m_ref = other.m_ref; ++ (*m_ref); m_obj = other.m_obj; } shared_ptr& operator=(const shared_ptr & other) { std::cout << "赋值运算符" << std::endl; if(m_obj == other.m_obj) { return *this; } if(m_obj) { --(*m_ref); clearMem(); } m_ref = other.m_ref; m_obj = other.m_obj; ++ (*m_ref); return *this; } shared_ptr(shared_ptr && other) : m_ref(nullptr), m_obj(nullptr){ std::cout << "移动构造函数" << std::endl; other.swap(*this); } shared_ptr& operator=(shared_ptr && other) { std::cout << "移动赋值运算符" << std::endl; if(m_obj) { --(*m_ref); clearMem(); } other.swap(*this); return *this; } T& operator*() const { return *m_obj;} T* operator->() const { return m_obj;} operator bool() const { return m_obj;} void clearMem() noexcept { std::cout << "清理内存" << std::endl; if(!m_ref) { return; } if(*m_ref == 0 && m_obj) { delete m_ref; delete m_obj; m_ref = nullptr; m_obj = nullptr; } } void swap(shared_ptr& other) { if(&other == this) { return; } std::swap(this->m_obj, other.m_obj); std::swap(this->m_ref, other.m_ref); } T* get() { return m_obj; } void getMessage(const std::string& name) { if(m_ref) { std::cout << name << " ref " << m_ref << ": " << *m_ref << std::endl; return; } std::cout << name << " nullptr" << std::endl; } private: size_t* m_ref; T* m_obj; }; struct person { int age = 0; bool sex = 0; person(int a, bool s) : age(a), sex(s) {} }; int main() { std::cout << "---------测试构造函数----------" << std::endl; shared_ptr p1(new person(10, true)); // 测试构造函数 p1.getMessage("p1"); std::cout << "-------测试拷贝构造函数--------" << std::endl; shared_ptr p2(p1); // 测试拷贝构造函数 p1.getMessage("p1"); p2.getMessage("p2"); shared_ptr p3(new person(9, false)); p3.getMessage("p3"); std::cout << "------测试重载赋值运算符-------" << std::endl; p1 = p3; // 测试重载赋值运算符 p1.getMessage("p1"); p2.getMessage("p2"); p3.getMessage("p3"); std::cout << "--------测试移动构造函数-------" << std::endl; shared_ptr p4(std::move(p3)); // 测试移动构造 p1.getMessage("p1"); p2.getMessage("p2"); p3.getMessage("p3"); p4.getMessage("p4"); std::cout << "--------测试移动赋值运算符-------" << std::endl; p3 = std::move(p1); // 移动赋值运算符 p1.getMessage("p1"); p2.getMessage("p2"); p3.getMessage("p3"); p4.getMessage("p4"); std::cout << "----------测试*和->的重载-------" << std::endl; std::cout << "*: " << p3->age << std::endl; std::cout << "->: " << (*p3).age << std::endl; return 0; }
---------测试构造函数---------- 构造函数 p1 ref 0x5598a590a2e0: 1 -------测试拷贝构造函数-------- 拷贝构造函数 p1 ref 0x5598a590a2e0: 2 p2 ref 0x5598a590a2e0: 2 构造函数 p3 ref 0x5598a590a320: 1 ------测试重载赋值运算符------- 赋值运算符 清理内存 p1 ref 0x5598a590a320: 2 p2 ref 0x5598a590a2e0: 1 p3 ref 0x5598a590a320: 2 --------测试移动构造函数------- 移动构造函数 p1 ref 0x5598a590a320: 2 p2 ref 0x5598a590a2e0: 1 p3 nullptr p4 ref 0x5598a590a320: 2 --------测试移动赋值运算符------- 移动赋值运算符 p1 nullptr p2 ref 0x5598a590a2e0: 1 p3 ref 0x5598a590a320: 2 p4 ref 0x5598a590a320: 2 ----------测试*和->的重载------- *: 9 ->: 9 析构函数 清理内存 析构函数 清理内存 析构函数 清理内存 析构函数 清理内存



