智能指针

mac2026-06-18  5

智能指针

智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。C++11新提供的两种智能指针的区别在于管理底层指针的方式: shared_ptr 允许多个指针指向同一个对象。unique_ptr 独占所指向的对象。标准库中还定义了一种名为 weak_ptr的指针,它是一种弱引用,指向share_ptr 所管理的对象。这三个指针都定义在 memory 头文件中。

1、shared_ptr

shared_ptr采用引用计数的方式管理所指向的对象。当有一个新的shared_ptr指向同一个对象时(复制shared_ptr等),引用计数加1。当shared_ptr离开作用域时,引用计数减1。当引用计数为0时,释放所管理的内存。

1.1、 shared_ptr 与 new

shared_ptr可以使用一个new表达式返回的指针进行初始化。但是,不能将一个new表达式返回的指针赋值给shared_ptr。

shared_ptr<int> p1(new int(1024)); cout<<*p1<<endl; >> 1024 shared_ptr<int> p2 = new(int(1024)); >>error

1.2、 shared_ptr 与 reset

shared_ptr可以通过reset方法重置指向另一个对象,此时原对象的引用计数减一。

auto p3 = p1; cout << p1.use_count() << endl; >> 2 p3.reset(new int(2048)); cout << p1.use_count() << endl; >> 1

2、unique_ptr

unique_ptr对于所指向的对象,正如其名字所示,是独占的。所以,不可以对unique_ptr进行拷贝、赋值等操作,但是可以通过release函数在unique_ptr之间转移控制权。

unique_ptr<int> up1(new int(1024)); cout<<"up1: "<<*up1<<endl; >> 1024 unique_ptr<int> up2(up1.release()); cout<<"up2: "<<*up2<<endl; >> 1024

3、weak_ptr

weak_ptr一般和shared_ptr配合使用。它可以指向shared_ptr所指向的对象,但是却不增加对象的引用计数。这样就有可能出现weak_ptr所指向的对象实际上已经被释放了的情况。因此,weak_ptr有一个lock函数,尝试取回一个指向对象的shared_ptr。

shared_ptr <int> ptr1 = new(int(1024)); weak_ptr <int> ptr2(ptr1); cout << ptr1.use_count() << endl; >> 1

4、总结

shared_ptr采用引用计数的方式管理所指向的对象。shared_ptr可以使用一个new表达式返回的指针进行初始化;但是,不能将一个new表达式返回的指针赋值给shared_ptr。一旦将一个new表达式返回的指针交由shared_ptr管理之后,就不要再通过普通指针访问这块内存。shared_ptr可以通过reset方法重置指向另一个对象,此时原对象的引用计数减一。unique_ptr对于所指向的对象,是独占的。不可以对unique_ptr进行拷贝、赋值等操作,但是可以通过release函数在unique_ptr之间转移控制权。unique_ptr可以作为函数的返回值和参数使用。weak_ptr一般和shared_ptr配合使用。它可以指向shared_ptr所指向的对象,但是却不增加对象的引用计数。weak_ptr有一个lock函数,尝试取回一个指向对象的shared_ptr。

5、实现智能指针

#include <iostream> #include <memory> using namespace std; template<typename T> class Smart_ptr{ private: T * smart_ptr; int smart_num; public: //构造函数 Smart_ptr(T *ptr=nullptr):smart_ptr(ptr){ if(!smart_ptr) smart_num = 0; else smart_num = 1; } //拷贝函数 Smart_ptr(Smart_ptr& ptr){ if(this!=&ptr){ ptr.smart_num++; this->smart_ptr = ptr.smart_ptr; this->smart_num = ptr.smart_num; } } //重载 = 运算符 Smart_ptr operator = (Smart_ptr& ptr){ if(this->smart_ptr == ptr.smart_ptr){ return *this; } ptr.smart_num++; this-> smart_ptr = ptr.smart_ptr; this-> smart_num = ptr.smart_num; return *this; } //重载 * 运算符 T& operator*(){ if(this->smart_ptr) return *(this->smart_ptr); } //重载 -> 运算符 T& operator->(){ if(this->smart_ptr) return this->smart_ptr; } //use_count函数 int use_count(){ return this->smart_num; } //析构函数 ~Smart_ptr(){ (this->smart_num)--; if(this->smart_num == 0){ delete this->smart_ptr; } } }; int main(){ Smart_ptr<int> sp1(new int(10)); cout << "operator*():" << *sp1 << endl; cout << "reference counting:(sp1) = " << sp1.use_count() << endl; Smart_ptr<int> sp2(sp1); cout << "copy reference counting:(sp1) = " << sp1.use_count() << endl; cout << "sp1.smart_num = " << sp1.use_count() << endl; Smart_ptr<int> sp3 = sp1; cout << "sp3 = " << *sp3 << endl; cout << "copy reference counting:(sp3) = " << sp3.use_count() << endl; }
最新回复(0)