文章目录
- 概述
- shared_ptr使用
概述
指针让我们在域边界之外拥有reference语义,然而,确保“pointer的寿命”和“其所指对象的寿命”一致却是件棘手的事。
C++11提供两大类型智能指针:shared_ptr和unique_ptr。
- shared_ptr实现共享式拥有的概念。多个shared_ptr指向同一个对象,当最后一个shared_ptr析构时,指向的对象也被释放,标准库还提供weak_ptr, bad_weak_ptr, enable_shared_from_this等辅助类。
- unique_ptr实现独占式拥有的概念。保证同一时间内只有一个指针指向对象,你可以移交所有权。
shared_ptr使用
shared_ptr的目标就是在其所指的对象不再被需要后,自动释放与之相关的资源。
构造:
shared_ptr<string> pStr1(new string("abc"));
shared_ptr<string> pStr2 = make_shared<string>("abc");
其中模板参数类型是指针指向的数据类型。
接受单一指针的构造函数是explicit的,因此不能进行隐式转换
shared_ptr<string> pStr = new string("abc"); // ERROR
shared_ptr<string> pStr{new string("abc")}; // OK
你也可以先声明shared_ptr再赋值一个指针给它。
shared_ptr<string> pStr;
pStr.reset(new string("abc"));
pStr = new string("abc"); // ERROR
你可以像使用指针一样使用shared_pointer
pStr->replace(0, 1, "J);
(*pStr)[0] = 'N'; // 改变string第一个元素
容器总是为传入的元素创建属于容器自己的拷贝,因此当把同一个shared_ptr重复添加到vector中时,多个shared_ptr将指向同一个string对象,当最后一个shared_ptr销毁时,会对其指向的对象调用delete
。
然而对于array,我们应该调用的是delete[]
,而不是delete
,因此创建一个指向array的shared_ptr是错误的
shared_ptr<int> p(new int[10]); // ERROR
我们在第二个参数指定deleter
shared_ptr<int> p(new int[10], [](int*p) { delete[] p; });
shared_ptr<int> p(new int[10], std::default_delete<int[]>()); // default_delete默认调用delete[]
C++17之前,只有unique_ptr支持数组类型的模板
unique_ptr<int[]> p(new int[10]); // 正确。并且能够正确调用delete[]
shared_ptr<int[]> p(new int[10]); // 编译错误
C++17之后,shared_ptr也支持数组类型的模板,并且也可以像原生数组一样取数组元素
shared_ptr<int[]> p(new int[10]); // C++17以后正确
p[0] = 0; // C++17之后正确
p->get()[1] = 1; // C++11不支持operator[]可使用此写法,与上述语句等价
注:本人在visual studio上使用shared_ptr<int[]> p(new int[10]);
没有检测到内存泄漏,可能是vs进行了优化?
参考: