c++ 手写智能指针shared_ptr
留个坑,回头在填。
#include <utility>
#include <iostream>
#include <cstddef>
#include <string>
template<typename T>
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<T>& other) {
std::cout << "拷贝构造函数" << std::endl;
m_ref = other.m_ref;
++ (*m_ref);
m_obj = other.m_obj;
}
shared_ptr& operator=(const shared_ptr<T>& 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<T>&& other) : m_ref(nullptr), m_obj(nullptr){
std::cout << "移动构造函数" << std::endl;
other.swap(*this);
}
shared_ptr& operator=(shared_ptr<T>&& 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<person> p1(new person(10, true)); // 测试构造函数
p1.getMessage("p1");
std::cout << "-------测试拷贝构造函数--------" << std::endl;
shared_ptr<person> p2(p1); // 测试拷贝构造函数
p1.getMessage("p1");
p2.getMessage("p2");
shared_ptr<person> 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<person> 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
析构函数
清理内存
析构函数
清理内存
析构函数
清理内存
析构函数
清理内存