- 智能指针
- unique_ptr
- shared_ptr
- weak_ptr
智能指针 unique_ptr
unique_ptr持有对对象的独有权,同一时刻只能有一个unique_ptr指向对象(通过禁止拷贝语义,只有移动语义来实现)
生命周期:从创建开始,直到离开作用域
离开作用域时,若其指向对象,则将其所指对象销毁(默认使用delete操作符,用户可指定其他操作)
unique_ptr实际是类模板,只不过是禁用了拷贝构造函数、赋值运算符=
重写了移动拷贝构造、->符号、*符号
独占指针的手工实现
#pragma once #includeshared_ptr#include using namespace std; template class SmartPointer { private: public: //构造函数 SmartPointer(T* ptr_ = nullptr): m_ptr(ptr_){} //支持移动拷贝构造 SmartPointer(SmartPointer &&p) noexcept : m_ptr(p.m_ptr) { cout << "移动拷贝" << endl; p.m_ptr = nullptr; } //禁用拷贝构造函数 SmartPointer(const SmartPointer &ptr_) = delete; //析构函数 ~SmartPointer() { if (m_ptr) { delete m_ptr; m_ptr = nullptr; } } //重载->符号 T* operator->() const noexcept{return m_ptr;} //重载 * 符号 T& operator* () const noexcept{return *m_ptr;} //禁用赋值运算符 SmartPointer &operator = (const SmartPointer &p) = delete; //释放智能指针地址 T* release() noexcept{ T *res = m_ptr; m_ptr = nullptr; return res; } //将托管指针重置为传入的指针 void reset(T* p = nullptr) noexcept{ std::swap(m_ptr, p); delete p; } //swap void swap(SmartPointer &p) noexcept{ std::swap(m_ptr, p.m_ptr); } //获取被管理对象的指针 T* get(){ return m_ptr; } //存放智能指针 T* m_ptr; };
共享指针,共享指针可以实现多个智能指针指向相同对象,使用计数机制来表明资源被几个指针共享,当我们release时,当前指针会释放资源所有权,计数-1。当计数为0时,资源会被释放。
#pragma once #includeweak_ptr#include using namespace std; template class Shared_ptr { private: //引用计数 int *count; //指针 T* _ptr; public: //构造函数 Shared_ptr():count(0), _ptr((T*)0){} //从原生指针构造 Shared_ptr(T* p):count(new int(1)), _ptr(p){} //拷贝构造函数,引用计数器+1,让该对象的指针指向形参对象的指针 Shared_ptr(Shared_ptr & other):count(&(++ *other.count)), _ptr(other._ptr){} //重载-> T* operator->(){return _ptr;} //重载* T& operator*() {return *_ptr;} //重载 = //如果原来shared_ptr已经有对象,则让其引用次数减1并判断引用是否为0(是否调用delete) //然后将新的对象引用次数加1 Shared_ptr & operator= (Shared_ptr & other) { //如果是自己赋给自己,则直接返回 if (this == &other) return *this; //计数器加1 ++*other.count; if (this->_ptr && 0 == --*this->count) { delete count; delete _ptr; cout << "delete ptr = " << endl; } this->_ptr = other._ptr; this->count = other.count; return *this; } //析构函数,使引用次数减一并判断引用是否为0(是否调用delete) ~Shared_ptr() { //判断ptr是否为空,并且count--后是否为0 if (_ptr && --*count == 0) { delete count; delete _ptr; cout << "delete ptr ~" << endl; } } //返回引用次数 int use_count(){return *count;} };
weak_ptr是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作,他可以从一个shared_ptr或另一个weak_ptr对象构造,他的构造和析构不会引起引用计数的增加或减少。没有重载*和->但可以使用lock获得一个可用的shared_ptr对象
weak_ptr的使用更为复杂一点,他可以指向shared_ptr指针指向的对象内存,却并不拥有该内存,而使用weak_ptr成员lock,则可返回其指向内存的一个shared_ptr对象,且在所指对象内存已经无效时,返回指针空值nullptr
使用例程
void check(weak_ptr&wp) { shared_ptr sp = wp.lock(); // 转换为shared_ptr if (sp != nullptr) { cout << "still " << *sp << endl; } else { cout << "pointer is invalid" << endl; } } int main() { shared_ptr sp1(new int(22)); shared_ptr sp2 = sp1; weak_ptr wp = sp1; // 指向shared_ptr 所指对象 cout << "count: " << wp.use_count() << endl; //打印计数器 cout << *sp1 << endl; // 22 cout << *sp2 << endl; // 22 check(wp); // still 22 sp1.reset(); cout << "count: " << wp.use_count() << endl; cout << *sp2 << endl; // 22 check(wp); // still 22 sp2.reset(); cout << "count: " << wp.use_count() << endl; check(wp); // pointer is invalid return 0; }



