shared_ptr共享的智能指针
一个指向堆上创建的对象的裸指针,raw_ptr;
一个指向内部隐藏的、共享的管理对象。share_count_object;
//初始化make_shared/reset
auto sp1 = make_shared<int>(1000);
//shared_ptr<int> sp1 = make_shared<int>(1000);
// 获取原始指针get
int* p = sp1.get();
// 不要保存p.get()的返回值 ,无论是保存为裸指针还是shared_ptr都是错误的
// 保存为裸指针不知什么时候就会变成空悬指针,保存为shared_ptr则产生了独立指针
// 不要delete p.get()的返回值 ,会导致对一块内存delete两次的错误
//当我们用shared_ptr管理动态数组时,需要指定删除器,因为shared_ptr的默认删除器不支持数组对象
std::shared_ptr<int> p3(new int[10], [](int* p) {delete[]p; });
//不要用一个原始指针初始化多个shared_ptr
int* ptr = new int;
shared_ptr<int> p1(ptr);
//shared_ptr<int> p2(ptr); xxxxxxxx
//不要在函数实参中创建shared_ptr
function(shared_ptr<int>(new int), g()); //有缺陷
//因为C++的函数参数的计算顺序在不同的编译器不同的约定下可能是不一样的
shared_ptr<int> p(new int);
function(p, g());
//通过shared_from_this()返回this指针
//让目标类通过std::enable_shared_from_this类,然后使用基类的成员函数shared_from_this()来返回this的shared_ptr
class A : public std::enable_shared_from_this<A>
{
public:
shared_ptr<A>GetSelf()
{
return shared_from_this(); //
}
~A()
{
cout << "Destructor A" << endl;
}
};
//避免循环引用:解决的办法是把A和B任何一个成员变量改为weak_ptr
unique_ptr独占的智能指针
unique_ptr是一个独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr
可以用作单例模式
unique_ptr<T> my_ptr(new T);
unique_ptr<T> my_other_ptr = my_ptr; // 报错,不能复制
unique_ptr<T> my_ptr(new T); // 正确
unique_ptr<T> my_other_ptr = std::move(my_ptr); // 正确
unique_ptr<T> ptr = my_ptr; // 报错,不能复制
auto upw1(std::make_unique<Widget>()); // with make func
//unique_ptr可以指向一个数组,代码如下所示
std::unique_ptr<int[]> ptr(new int[10]);
ptr[9] = 9;
std::shared_ptr<int[]> ptr2(new int[10]); // 这个是不合法的
//unique_ptr指定删除器和shared_ptr有区别
std::shared_ptr<int> ptr3(new int(1), [](int* p) {delete p; }); // 正确
std::unique_ptr<int> ptr4(new int(1), [](int* p) {delete p; }); // 错误
//unique_ptr需要确定删除器的类型,所以不能像shared_ptr那样直接指定删除器,可以这样写:
std::unique_ptr<int, void(*)(int*)> ptr5(new int(1), [](int* p) {delete p; }); //正确
总结: 如果希望只有一个智能指针管理资源或者管理数组就用unique_ptr,如果希望多个智能指针管理同一个资源就用shared_ptr。
weak_ptr弱引用的智能指针
weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象. 进行该对象的内存管理的是那个强引用的shared_ptr, weak_ptr只是提供了对管理对象的一个访问手段。
//通过use_count()方法获取当前观察资源的引用计数
shared_ptr<int> sp(new int(10));
weak_ptr<int> wp(sp);
cout << wp.use_count() << endl; //结果讲输出1
//通过expired()方法判断所观察资源是否已经释放
shared_ptr<int> sp(new int(10));
weak_ptr<int> wp(sp);
if (wp.expired())
cout << "weak_ptr无效,资源已释放";
else
cout << "weak_ptr有效";//输出
//通过lock方法获取监视的shared_ptr
std::weak_ptr<int> gw;
void f()
{
auto spt = gw.lock();
if (gw.expired()) {
cout << "gw无效,资源已释放";
}
else {
cout << "gw有效, *spt = " << *spt << endl;
}
}
int main()
{
{
auto sp = std::make_shared<int>(42);
gw = sp;
f();
}
f();
return 0;
}
weak_ptr返回this指针
shared_ptr章节中提到不能直接将this指针返回shared_ptr,需要通过派生std::enable_shared_from_this类,并通过其方法shared_from_this来返回指针,原因是std::enable_shared_from_this类中有一个weak_ptr,这个weak_ptr用来观察this智能指针,调用shared_from_this()方法是,会调用内部这个weak_ptr的lock()方法,将所观察的shared_ptr返回。
weak_ptr解决循环引用问题
weak_ptr使用注意事项
weak_ptr在使用前需要检查合法性。
在使用wp前需要调用wp.expired()函数判断一下。