1. 智能指针的初始化
// 1. 智能指针的初始化
shared_ptr<myclass> p(new myclass);
shared_ptr<myclass> p2 = p;
shared_ptr<int> ptr; //未初始化的智能指针,可以通过reset进行初始化
ptr.reset(new int(1));
// 应该优先使用make_shared构造智能指针,更高效
shared_ptr<myclass> p3 = make_shared<myclass>();
p3->print();
// 不能将一个原始指针直接赋值给一个指针指针,例如下面是错误的
// shared_ptr<int> p4 = new int(1); //编译报错,不允许直接赋值
2. 获取原始指针
shared_ptr<myclass> ptr1(new myclass);
myclass* p_original = ptr1.get();
p_original->print();
3. 指定删除器
// 3. 指定删除器
// 3.1 智能指针初始化可以指定删除器,当p31的引用计数为0时,会自动调用删除器释放对象的内存,删除器可以是一个类模板函数
shared_ptr<myclass> p31;
p31.reset(new myclass("p31"), DeleteIntPtr);
shared_ptr<myclass> p32(new myclass("p32"), [](myclass* p){cout<< p->name<<endl; delete p;});
// 3.2 指定删除器在哪方面可以用到呢?当我们用shared_ptr 管理动态数组时,需要指定删除器,因为shared_ptr的默认删除器不支持数组对象
shared_ptr<myclass>p33(new myclass[10], [](myclass* p){ delete[] p;});
cout<< "p33 " <<p33.get()[5].name<<endl;
// 3.3 还可以通过std::default_delete 作为删除器,该删除器的内部是通过调用delete来实现功能的
shared_ptr<myclass> p34(new myclass[10], std::default_delete<myclass[]>());
cout<<"p34 "<< p34.get()[8].name<<endl;
// 3.4 还可以封装一个make_shared_array 方法让shared_ptr支持数组
shared_ptr<myclass> p35 = make_shared_array<myclass>(10);
cout<<"p35 = "<<p35.get()[9].name<<endl;
4.shared_ptr 需要注意的问题
// 4.1 不要用一个原始指针初始化多个shared_ptr例如下面的:
int* p4 = new int;
shared_ptr<int> p41(p4);
shared_ptr<int> p42(p4);
// 4.2 不要在函数实参中创建shared_ptr,如下
// function(shared_ptr<int>(new int),g());//有问题
// 因为c++编译器对参数的解读不同,有的编译器会从左向右,有的会从右向左,所以可能会先new 然后调用g()函数,如果g函数异常,而shared_ptr<int> 还没创建,则int 内存泄露
// 正确的做法应如下:
// shared_ptr<int> p43(new int);
// f(p, g());
// 4.3 通过shared_from_this() 返回指针,不要将this指针作为shared_ptr返回出来,因为this是裸指针,会导致重复析构
// 4.4 避免循环引用