智能指针
智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。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;
}