智能指针shared_ptr(C++11)
当复制或拷贝时,引用计数加 1,当智能指针析构时,引用计数减 1,如果计数为零,代表已经没有指针指向这块内存,那么我们就释放它!这就是 shared_ptr。
1、构造函数
shared_ptr<T> sp ; //空的 shared_ptr,可以指向类型为 T 的对象
shared_ptr<T> sp1(new T()) ;//定义 shared_ptr,同时指向类型为 T 的对象
shared_ptr<T[]> sp2 ; //空的 shared_ptr,可以指向类型为 T[的数组对象 C++17 后支持
shared_ptr<T[]> sp3(new T[]{...}) ;//指向类型为 T 的数组对象 C++17 后支持
shared_ptr<T> sp4(NULL, D()); //空的 shared_ptr,接受一个 D 类型的删除器,使用 D
释放内存
shared_ptr<T> sp5(new T(), D()); //定义 shared_ptr,指向类型为 T 的对象,接受一个 D类型的删除器,使用 D 删除器来释放内存
2、初始化
方式一、构造函数
shared_ptrr<int> up1(new int(10)); //int(10) 的引用计数为 1
shared_ptrr<int> up2(up1); //使用智能指针 up1 构造 up2, 此时 int(10) 引用计数为 2
方式二、使用 make_shared 初始化对象,分配内存效率更高
//make_shared 函数的主要功能是在动态内存中分配一个对象并初始化它,返回指向此对象的 shared_ptr; 用法:
make_shared<类型>(构造类型对象需要的参数列表);
shared_ptr<int> p4 = make_shared<int>(2); //多个参数以逗号','隔开,最多接受十个
shared_ptr<string> p4 = make_shared<string>("字符串");
3、赋值
shared_ptrr<int> up1(new int(10)); //int(10) 的引用计数为 1
shared_ptr<int> up2(new int(11)); //int(11) 的引用计数为 1
up1 = up2;//int(10) 的引用计数减 1,计数归零内存释放,up2 共享 int(11)给 up1, int(11)的引用计数为 2
4、主动释放对象
shared_ptrr<int> up1(new int(10));
up1 = nullptr ;//int(10) 的引用计数减 1,计数归零内存释放
或
up1 = NULL;
5、重置
up.reset() ; //将 p 重置为空指针,所管理对象引用计数 减 1
up.reset(p1); //将 p 重置为 p1(的值),p 管控的对象计数减 1,p 接管对 p1 指针的管控
up.reset(p1,d); //将 p 重置为 p(的值),p 管控的对象计数减 1 并使用 d 作为删除器
6、交换
std::swap(p1,p2); //交换 p1 和 p2 管理的对象,原对象的引用计数不变
p1.swap(p2);//同上
智能指针weak_ptr(C++11)
weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少. 同时 weak_ptr 没有重载*和->但可以使用 lock 获得一个可用的 shared_ptr 对象。
#include<iostream>
#include<memory>
using namespace std;
class Gril;
class Boy {
public:
Boy() {
cout << "Boy构造函数" << endl;
};
~Boy() {
cout << "Boy析构函数" << endl;
}
void boySey(shared_ptr<Gril>& g) {
Grils = g;
}
private:
shared_ptr<Gril> Grils;//shared_ptr 作为被管控的对象的成员时,因循环引用造成无法释放资源,用weak_prt这个智能指针就可解决
// weak_ptr<Gril>Grils; //Boy类中或Gril类中用一个即可
};
class Gril {
public:
Gril() {
cout << "Gril构造函数" << endl;
}
~Gril() {
cout << "Gril析构函数" << endl;
}
void grilSet(shared_ptr<Boy>& b) {
Boys = b;
}
private:
shared_ptr<Boy> Boys;//shared_ptr 作为被管控的对象的成员时,因循环引用造成无法释放资源,用weak_prt这个智能指针就可解决
//weak_ptr<Boy>Boys;//Boy类中或Gril类中用一个即可
};
int main() {
shared_ptr<Boy> boy1(new Boy());
shared_ptr<Gril> gril1(new Gril());
boy1->boySey(gril1);
gril1->grilSet(boy1);
return 0;
}