已经被弃用,替代方案是unique_ptr.
被弃用的原因:
1.不能使用vector等容器保存auto_ptr
2.不能从函数中返回auto_ptr类型
//已经被弃用,替代方案是unique_ptr.
//
//被弃用的原因:
//
//1.不能使用vector等容器保存auto_ptr
//
//2.不能从函数中返回auto_ptr类型
//3.在使用这样的code时,容易让开发者忘记,还有事情要做。
void main(){
cout << "....." << endl;
auto_ptr<string> pstr(new string("abc"));
auto_ptr<string> pstr1(pstr);
//代码执行到这里, pstr1中是"abc",pstr变成了empty,
if (pstr.get() ==nullptr) {
cout << "pstr.get() == nullptr" << endl; //结果走到这一行
}
else {
cout << "pstr.get() exsit " << endl;
}
//如果后面我们再次使用pstr就会有问题。
cout << "断点在这里";
}
独占式指针,意思是:同一个时间内,只有一个指针能够指向该指针。
当然,该对象的所有权还是可以移交出去的。
当这个unique_ptr被销毁的时候,指向的对象也会销毁。
在不指定删除器的情况下,大小和裸指针一样大。在指定了删除器的情况下,有可能比裸指针大。
? ?如果删除器是 函数指针,则会变大
? ? ? ? 如果删除器是 lambda 表达式,则不会变大
所以,只有当最后一个指向该对象的shared_ptr指针不需要再指向该对象时候,那么这个shared_ptr才会去析构所指向的对象。
????????a.当最后一个shared_ptr指向其他对象的时候
????????b.当shared_ptr被析构的时候,比如说;在局部函数中,shared_ptr的作用域结束了,自然会被回收,紧跟着它指向的内存也会被释放
shared_ptr<int> pi; // pi 是nullptr?
shared_ptr<int> pi1(); // 注意这里:这不是定义一个shared_ptr<int> 变量, 这里:pi1()是函数声明。因此不会有build error。
void func130(shared_ptr<int> tempptr) {//引用计数变成4 tempptr = shared_ptr 100 [4 strong refs] [make_shared]
cout << "xxx" << endl;
}
shared_ptr<int> func131(shared_ptr<int>& temp) {
return temp;
}
void main(){
shared_ptr<int> pi; // pi 是nullptr?
if (pi == nullptr) {
cout << "pi == nullptr" << endl;
}
shared_ptr<int> pi1(); // 注意这里:这不是定义一个shared_ptr<int> 变量, 这里:pi1()是函数声明。因此不会有build error。
//pi1 = make_shared<int>(100);//build error,pi1是函数声明。
//由于shared_ptr是explicit的。因此要显示的实例化
shared_ptr<int> pi2(new int);//pi2 = shared_ptr -842150451 [1 strong ref] [default] .........[ptr] = 0x000001f54ed67730 {-842150451}
shared_ptr<int> pi3(new int());//pi3 = shared_ptr 0 [1 strong ref] [default].....[ptr] = 0x000001f54ed70bd0 {0}
shared_ptr<int> pi4(new int(100));//pi4 = shared_ptr 100 [1 strong ref] [default]
//让pi5 和 pi3指向同一块内存
shared_ptr<int> pi5(pi3);// [ptr] = 0x000001f54ed70bd0 {0}
//通过make_shared 实例化.
//make_shared 是一个模版函数,
//make_shared被认为是 安全,高效的。
//make_shared生成的shared_ptr指针没有办法自定义删除器,
//如下代码的意思是:通过 make_shared函数分配一块大小为int的空间,该空间的值是200,并用该空间的指针初始化 pi6
shared_ptr<int> pi6(make_shared<int>(200));
//打印结果
cout << *pi6 << endl; //200
//赋值
pi = make_shared<int>(100);
cout << *pi << endl;//100
*pi6 = 999; //999
cout << *pi6 << endl;
//关于 shared_ptr的强引用指针的增加的例子。
auto p6 = make_shared<int>(100); //强引用是1
auto p7(p6);//强引用变成2
auto p8(p7);//强引用变成3
//当智能指针当做实参往函数里面传递的时候,强引用计数也会+1,但是当形参使用完毕后,又会减1
func130(p7);
//当func130方法执行完毕后,强引用又变回3
//当函数返回值是智能指针时,计算器也会+1
auto p9 = func131(p7); //强引用变成4
//关于 shared_ptr的强引用指针的减少的例子。
p9 = nullptr;//强引用变成3
p8 = make_shared<int>(200);//强引用变成2, p8的指向变化的时候,也会-1
cout << "断点在这里";
}
//使用shared_ptr管理动态数组:
shared_ptr<int[]> str7111(new int[3]());//new int[3]()带小括号,这三个int的值默认都会给0
shared_ptr<int[]> str7(new int[3]);
for (int i = 0; i < 3;i++) {
str7[i] = i*3 + 6;
}
for (int i = 0; i < 3; i++) {
cout << "str7[" << i<<"] = " <<str7[i]<< endl;
}
int aaaaaa = str7.use_count();//count 是 1
shared_ptr<Teacher121[]> str8(new Teacher121[3]());//new Teacher121[3]()带小括号,不会给三个Teacher121赋任何值
shared_ptr<Teacher121[]> str9(new Teacher121[3]);
str8[0] = Teacher121(20);
str8[1] = Teacher121(30);
str8[2] = Teacher121(40);
cout << "--------" << endl;
for (int i = 0; i < 3;i++) {
str8[i].print();
}
cout << "--------" << endl;
str9[0] = Teacher121(200);
str9[1] = Teacher121(300);
str9[2] = Teacher121(400);
cout << "--------" << endl;
for (int i = 0; i < 3; i++) {
str9[i].print();
}
cout << "--------" << endl;
返回管理当前对象的不同 shared_ptr
实例(包含 this )数量。若无管理对象,则返回 ?0? 。
多线程环境下, use_count 返回的值是近似的(典型实现使用 memory_order_relaxed 加载)
std::shared_ptr<T>::use_count
long use_count() const noexcept;
返回管理当前对象的不同 shared_ptr 实例(包含 this )数量。若无管理对象,则返回 ?0? 。
多线程环境下, use_count 返回的值是近似的(典型实现使用 memory_order_relaxed 加载)
参数
(无)
返回值
管理当前对象的 shared_ptr 实例数量,或若无被管理对象则为 ?0? 。
注意
常用使用包括
?与 ?0? 比较。若 use_count 返回零,则智能指针为空且不管理对象(无论被存储指针是否为空)。多线程环境下,这不隐含被管理对象的析构函数已完成。
?与 1 比较。若 use_count 返回 1 ,则无其他拥有者。(被弃用成员函数 unique() 为此使用情况提供。)多线程环境中,这不隐含对象可以安全修改,因为先前拥有者对被管理对象的访问可能未完成,而因为新的共享拥有者可以同时引入,例如用 std::weak_ptr::lock 。
//关于 shared_ptr的强引用指针的增加的例子。
auto p6 = make_shared<int>(100); //强引用是1
auto p7(p6);//强引用变成2
auto p8(p7);//强引用变成3
//当智能指针当做实参往函数里面传递的时候,强引用计数也会+1,但是当形参使用完毕后,又会减1
func130(p7);
//当func130方法执行完毕后,强引用又变回3
//当函数返回值是智能指针时,计算器也会+1
auto p9 = func131(p7); //强引用变成4
//关于 shared_ptr的强引用指针的减少的例子。
p9 = nullptr;//强引用变成3
p8 = make_shared<int>(200);//强引用变成2, p8的指向变化的时候,也会-1
int count = p6.use_count();//返回2
std::shared_ptr<T>::unique
bool unique() const noexcept;
(C++17 中弃用)
(C++20 中移除)
检查 *this 是否管理当前对象的仅有 shared_ptr 实例,即是否 use_count() == 1 。
参数
(无)
返回值
若 *this 否管理当前对象的仅有 shared_ptr 实例则为 true ,否则为 false 。
注意
此函数于 C++17 中被弃用并于 C++20 中移除,因为 use_count 在多线程环境中只是估计(见 use_count 中的“注意”)。
如果reset()括号中没有参数,则 ptr==nullptr.这意味着,如果ptr是唯一的指向内存的指针,则内存会被释放。如果有多个指针指向该内存,则 强引用-1.
如果reset(Y* newptr)括号中有参数,会将ptr的指向 newptr 的内存。如果ptr是唯一的之前的指向内存的指针,则内存会被释放。如果有多个指针指向该内存,则 强引用-1.
std::shared_ptr<T>::reset
void reset() noexcept;
(1) (C++11 起)
template< class Y >
void reset( Y* ptr );
(2) (C++11 起)
template< class Y, class Deleter >
void reset( Y* ptr, Deleter d );
(3) (C++11 起)
template< class Y, class Deleter, class Alloc >
void reset( Y* ptr, Deleter d, Alloc alloc );
(4) (C++11 起)
以 ptr 所指向的对象替换被管理对象。能可选地提供删除器 d ,之后在无 shared_ptr 对象占有该对象时以之销毁新对象。默认以 delete 表达式为删除器。始终选择对应提供类型的 delete 表达式,这是函数以使用分离的形参 Y 的模板实现的理由。
若 *this 已占有对象,且它是最后一个占有该对象的 shared_ptr ,则通过所占有的删除器销毁对象。
若 ptr 所指向的对象已被占有,则函数通常会导致未定义行为。
1) 释放被管理对象的所有权,若存在。调用后, *this 不管理对象。等价于 shared_ptr().swap(*this); 。
2-4) 以 ptr 所指向对象替换被管理对象。 Y 必须是完整类型且可隐式转换为 T 。另外:
2) 以 delete 表达式为删除器。合法的 delete 表达式必须可用,即 delete ptr 必须为良式,拥有良好定义行为且不抛任何异常。等价于 shared_ptr<T>(ptr).swap(*this); 。
3) 以指定的删除器 d 为删除器。 Deleter 必须对 T 类型可调用,即 d(ptr)必须为良构,拥有良好定义行为且不抛任何异常。 Deleter 必须可复制构造 (CopyConstructible) ,且其复制构造函数和析构函数必须不抛异常。等价于 shared_ptr<T>(ptr, d).swap(*this); 。
4) 同 (3) ,但额外地用 alloc 的副本分配内部使用的数据。 Alloc 必须是分配器 (Allocator) 。复制构造函数和析构函数必须不抛异常。等价于 shared_ptr<T>(ptr, d, alloc).swap(*this); 。
参数
ptr - 指向要取得所有权的对象的指针
d - 为删除对象而存储的删除器
alloc - 内部存储所用的分配器
返回值
(无)
异常
2) 若无法获得要求的额外内存则为 std::bad_alloc 。可能因其他错误抛出实现定义的异常。若出现异常则调用 delete ptr 。
3-4) 若无法获得要求的额外内存则为 std::bad_alloc 。可能因其他错误抛出实现定义的异常。若出现异常则调用 d(ptr) 。
//reset函数,没有参数
shared_ptr<string> str1(new string("abc"));
shared_ptr<string> str2 = str1;// str1 和 str2都指向“abc”这块内存,强引用数量2
str1.reset();//这时候 str1变成nullptr,指向“abc”这块内存的强引用数量变成1
str2.reset();// 这时候 str2变成nullptr,指向“abc”这块内存的强引用数量变成0,于是这块内存被释放
shared_ptr<string> str3(new string("def"));
shared_ptr<string> str4(str3);// str3 和 str4都指向“def”这块内存,强引用数量2
str4.reset(new string("iou")); //str4指向新的内存,str3指向的内存的 强引用变成1,str4的强引用变成1,不过str4指向另一个内存空间了
//str3 [ptr] = 0x00000237028fbc30 "def"
//strs4 [ptr] = 0x00000237028fba00 "iou"
返回存储的指针。
注意,返回的存储的指针,我们也叫做裸指针,
由于这个裸指针还是依赖于 shared_ptr存在,因此程序员不要手动的delete 它,如果delete了,那么shared_ptr在释放这块内存的时候,delete的时候,这块指向的空间会被delete两次,就会造成程序异常。
std::shared_ptr<T>::get
T* get() const noexcept;
(C++17 前)
element_type* get() const noexcept;
(C++17 起)
返回存储的指针。
参数
(无)
返回值
存储的指针。
注意
shared_ptr 可能在存储指向一个对象的指针时共享另一对象的所有权。 get() 返回存储的指针,而非被管理指针。
shared_ptr<string> str6(new string("qqq"));
string * s = str6.get();
cout << "s = " << s << " *s = " << *s << endl;
//delete s;//程序员不要手动的delete,否则会运行时异常。
*s = "www";
cout << "s = " << s << " *s = " << *s << endl;
//那么get()方法的应用场景主要是为了第三方库,很大程度上第三方库的参数可能是 裸指针,而不是智能指针
std::shared_ptr<T>::swap
void swap( shared_ptr& r ) noexcept;
(C++11 起)
交换 *this 与 r 的存储指针值与所有权。不调整引用计数,若它们存在。
参数
r - 要与之交换内容的智能指针
返回值
(无)
从前面的知识中知道,在使用智能指针的时候,我们不需要手动的delete,那么C++编译器是如何自动的delete的呢?这里就引出了 删除器 的概念。
实际上C++17之前 shared_ptr内部就是 使用关键字 delete ptr完成的。也正是由于由于shared_ptr 内部只有delete ptr,没有delete[] ptr,因此在C++17之前 如果shared_ptr管理的是动态数组,那么就需要自己指定删除器。
如果知道是C++17之前不支持呢?
参考C++ 文档:shared_ptr中的关于[]的介绍
operator[] (C++17) | 提供到被存储数组的带下标访问 (公开成员函数) |
class Teacher122 {
public:
Teacher122() {
cout << "Teacher122 没有参数的构造函数被执行 " << this << endl;
}
Teacher122(int age) :m_age(age) {
cout << "Teacher122 int age 构造函数被执行 " << this<< endl;
}
void print() {
cout << "age = " << this->m_age << " " << this << endl;
}
~Teacher122() {
cout << "Teacher122 析构函数被调用 " << this << endl;
}
void setAge(int age) {
this->m_age = age;
}
private:
int m_age;
};
void mydelete(int *p) {
cout << "mydelete int called" << endl;
delete p;
p = nullptr;
}
void mydeletearr(int *p) {
cout << "mydeletearr int called" << endl;
delete [] p;
p = nullptr;
}
void mydeleteTeacher122(Teacher122 *p) {
cout << "mydeleteTeacher122 called" << endl;
delete[] p;
p = nullptr;
}
void main() {
//C++17之前 shared_ptr管理 普通 怎么写
shared_ptr<int> intptr(new int(200),mydelete);
intptr = nullptr;
cout << "-----------" << endl;
//C++17之前 shared_ptr管理 数组怎么写?由于没有下标[]可以操作,因此,只能通过get得到裸指针,然后通过裸指针操作数据
shared_ptr<int> intarrptr(new int[3], mydeletearr);
for (int i = 0; i < 3;i++) {
//注意,要获得数据,只能通过get()方法得到裸指针,该裸指针肯定是指向int的,因此每次加1都是跳4个字节,因此可以通过 *(ptr + i)给数据赋值。
*(intarrptr.get()+i) = 9 * i;
}
for (size_t i = 0; i < 3; i++)
{
cout << "*(intarrptr.get()+i = " << *(intarrptr.get() + i) << endl;
}
intarrptr = nullptr;
//结果:
//*(intarrptr.get()+i = 0
//*(intarrptr.get() + i = 9
//* (intarrptr.get() + i = 18
//mydeletearr int called
C++17之前 shared_ptr管理 普通类 怎么写
shared_ptr<Teacher122> pteacher1(new Teacher122());
pteacher1->print();
pteacher1->setAge(78);
pteacher1->print();
cout << "mmm" << endl;
pteacher1 = nullptr;
//Teacher122 没有参数的构造函数被执行 00000130B9427730
// age = -842150451 00000130B9427730
// age = 78 00000130B9427730
// mmm
// Teacher122 析构函数被调用 00000130B9427730
C++17之前 shared_ptr管理 普通类数组 怎么写
shared_ptr<Teacher122> pteacherarr(new Teacher122[3], mydeleteTeacher122);
for (int i = 0; i < 3;i++) {
//get()函数返回裸指针
Teacher122* temp = pteacherarr.get() + i;
temp->setAge((i + 1) * 30);
}
for (int i = 0; i < 3; i++) {
Teacher122* temp = pteacherarr.get() + i;
temp->print();
}
//Teacher122 没有参数的构造函数被执行 00000130B94322F8
// Teacher122 没有参数的构造函数被执行 00000130B94322FC
// Teacher122 没有参数的构造函数被执行 00000130B9432300
// age = 30 00000130B94322F8
// age = 60 00000130B94322FC
// age = 90 00000130B9432300
// mydeleteTeacher122 called
// Teacher122 析构函数被调用 00000130B9432300
// Teacher122 析构函数被调用 00000130B94322FC
// Teacher122 析构函数被调用 00000130B94322F8
}
//b.删除器可以是一个lambda表达式
cout << "删除器是一个lambda表达式start " << endl;
shared_ptr<Teacher122> pteacherarr2(new Teacher122[3], [](Teacher122 *p) {
delete[] p;
p = nullptr;
});
for (int i = 0; i < 3; i++) {
//get()函数返回裸指针
Teacher122* temp = pteacherarr2.get() + i;
temp->setAge((i + 1) * 50);
}
for (int i = 0; i < 3; i++) {
Teacher122* temp = pteacherarr2.get() + i;
temp->print();
}
cout << "删除器是一个lambda表达式end " << endl;
//删除器是一个lambda表达式start
// Teacher122 没有参数的构造函数被执行 0000025294FC1D58
// Teacher122 没有参数的构造函数被执行 0000025294FC1D5C
// Teacher122 没有参数的构造函数被执行 0000025294FC1D60
// age = 50 0000025294FC1D58
// age = 100 0000025294FC1D5C
// age = 150 0000025294FC1D60
// 删除器是一个lambda表达式end
// Teacher122 析构函数被调用 0000025294FC1D60
// Teacher122 析构函数被调用 0000025294FC1D5C
// Teacher122 析构函数被调用 0000025294FC1D58
default_delete是标准库里的模板类
cout << "删除器是一个default_delete 标准库模版 start " << endl;
shared_ptr<Teacher122> pteacherarr3(new Teacher122[3], default_delete<Teacher122[]>());
for (int i = 0; i < 3; i++) {
//get()函数返回裸指针
Teacher122* temp = pteacherarr3.get() + i;
temp->setAge((i + 1) * 60);
}
for (int i = 0; i < 3; i++) {
Teacher122* temp = pteacherarr3.get() + i;
temp->print();
}
cout << "删除器是一个default_delete 标准库模版 end " << endl;
//删除器是一个default_delete 标准库模版 start
// Teacher122 没有参数的构造函数被执行 000001CD1E9D2488
// Teacher122 没有参数的构造函数被执行 000001CD1E9D248C
// Teacher122 没有参数的构造函数被执行 000001CD1E9D2490
// age = 60 000001CD1E9D2488
// age = 120 000001CD1E9D248C
// age = 180 000001CD1E9D2490
// 删除器是一个default_delete 标准库模版 end
// Teacher122 析构函数被调用 000001CD1E9D2490
// Teacher122 析构函数被调用 000001CD1E9D248C
// Teacher122 析构函数被调用 000001CD1E9D2488
写法如下,
//使用shared_ptr管理动态数组:
shared_ptr<int[]> str7111(new int[3]());//new int[3]()带小括号,这三个int的值默认都会给0
shared_ptr<int[]> str7(new int[3]);
for (int i = 0; i < 3;i++) {
str7[i] = i*3 + 6;
}
for (int i = 0; i < 3; i++) {
cout << "str7[" << i<<"] = " <<str7[i]<< endl;
}
int aaaaaa = str7.use_count();//count 是 1
shared_ptr<Teacher121[]> str8(new Teacher121[3]());//new Teacher121[3]()带小括号,不会给三个Teacher121赋任何值
shared_ptr<Teacher121[]> str9(new Teacher121[3]);
str8[0] = Teacher121(20);
str8[1] = Teacher121(30);
str8[2] = Teacher121(40);
cout << "--------" << endl;
for (int i = 0; i < 3;i++) {
str8[i].print();
}
cout << "--------" << endl;
str9[0] = Teacher121(200);
str9[1] = Teacher121(300);
str9[2] = Teacher121(400);
cout << "--------" << endl;
for (int i = 0; i < 3; i++) {
str9[i].print();
}
cout << "--------" << endl;
//9.shared_ptr的使用陷阱
//a.当返回值是 shared_ptr 的时候,要注意是不是有变量接受。
//如果没有变量接受,那么离开 func135方法的作用域后,shared_ptr 就会销毁
//如果有变量接受,则shared_ptr的强引用+1
shared_ptr<int> func135() {
return make_shared<int>(199);
}
void main() {
func135();
cout << "duandian 1" << endl;
shared_ptr<int> aa = func135();//aa = shared_ptr 199 [1 strong ref] [make_shared]
cout << "duandian 2" << endl;
}
最好不要 让 裸指针和智能指针混用。
一旦让一个裸指针初始化了多个shared_ptr.
当ptr1销毁的时候,裸指针也会销毁。但是ptr2还是指向的裸指针,就会有问题。
void fun136(shared_ptr<int> tempptr){
cout << "fun136 called" << endl;
}
void main() {
//b.慎用裸指针
// 最好不要 让 裸指针和智能指针混用。
// b1如果混用, 注意:一个裸指针只能初始化一个shared_ptr,
// 一旦让一个裸指针初始化了多个shared_ptr.
// 当ptr1销毁的时候,裸指针也会销毁。但是ptr2还是指向的裸指针,就会有问题。
int *p = new int(100);
shared_ptr<int> ptr1(p);
//shared_ptr<int> ptr2(p);//让裸指针p初始化了2个shared_ptr,一旦运行,就run time exception
// b2,一旦裸指针初始化了智能指针,这个裸指针的生命管理就交给智能指针了,就不要去delete 裸指针了。
int *p2 = new int(200);
shared_ptr<int> ptr3(p2);
//delete p2;//手动delete,就会有run time exception
// b3, 裸指针作为临时对象shared_ptr的初始化参数,在临时对象shared_ptr销毁的时候,裸指针也会被释放。
int *p3 = new int(300);
fun136(shared_ptr<int>(p3));
cout << "duandian" << endl;//由于 临时变量 shared_ptr<int>(p3) 传递到 fun136方法的时候,强引用计数不会+1,因此当func136执行完毕后,引用计数-1变成0,临时便令shared_ptr<int>(p3)会被销毁,进而裸指针p也会被delete
//注意这里p3已经被释放了,就不要再用了
// b4.shared_ptr通过get方法获得的指针不要绑定在其他的指针上,也不要delete
shared_ptr<int> p5(new int(500));
shared_ptr<int> p6(make_shared<int>(600));
int * pp5 = p5.get();
cout << "duandian 2 " << endl;
//shared_ptr<int> p7(pp5);//这里不能将裸指针 pp5 绑定到其他 智能指针上了
//delete pp5;//也不要delete 裸指针
}
//不要把类对象this 做为shared_ptr的参数,这其实很好理解。
//假设被人调用了,那么this这个裸指针 就被两个不同的 shared_ptr指向了。
//class Teacher136 {
//public:
// shared_ptr<Teacher136> getTeacher136() {
// return shared_ptr<Teacher136>(this);
// }
//};
//上述问题如何解决呢?
//让 Teacher136 继承enable_shared_from_this<Teacher137>.
//返回shared_from_this();
class Teacher137 :public enable_shared_from_this<Teacher137>{
public:
shared_ptr<Teacher137> getTeacher137() {
return shared_from_this();
}
int mage;
};
void main() {
//Teacher137 tea;
//tea.mage = 10;
//注意使用,因为返回的shared_from_this(),那么意味着之前一定是要有 智能指针指向这个this的,因此要先弄出来一个智能指针
Teacher137 *pt = new Teacher137();
shared_ptr<Teacher137> ptea(pt);
shared_ptr<Teacher137> ptea1 = ptea->getTeacher137();
ptea->mage = 90;
cout << pt->mage << " " << ptea1->mage << endl;
}
shared_ptr<int> p1(make_shared<int>(100));
shared_ptr<int> p2?= move(p1);
//10.移动语义也使用于智能指针
shared_ptr<int> p1(make_shared<int>(100));
shared_ptr<int> p2 = move(p1);
// 从测试结果看: p1变成empty 了,p2变成指向 100的那块内存了,
// 这说明shared_ptr类中对于移动构造的实现是:转移裸指针的所属,并将强引用那块的指针也转移了
cout << " " << endl;
类模版
用来辅助shared_ptr进行工作的。
shared_ptr? 和? weak_ptr 所指向对象的引用计数,有两种,一种是强引用,一种是弱引用。
强引用指的是 shared_ptr指向的个数
弱引用指的是 weak_ptr指向的个数。
weak_ptr指向一个由shared_ptr管理的对象。
当shard_ptr指向的对象的强引用 计数变成0的时候,该对象会析构,这时候是不用看 weak_ptr的弱引用计数的。
weak_ptr 不能独立存在,必须要依附于shard_ptr存在。
weak_ptr 监视 shard_ptr 的生命周期用的,是对shard_ptr的一种扩展。
通过 use_count(); 可以获取强引用的计数
通过 expired(); 是否过期,如use_count()返回0,则返回true。
如上两个函数给人的感觉好像重复了, 只是多了一个判断?查了下 C++的文档,好像也没有特殊的地方。有知道的小伙伴可以帮忙回复一下。
通过 reset();可以将自己的这个弱引用==nullptr,弱引用计数-1
lock();检查weak_ptr 指向的对象是否存在,如存在,返回一个指向该对象的 shared_ptr(这时候对象的强引用计数就会+1)
void main() {
shared_ptr<string> str1(new string("abc"));
weak_ptr<string> wstr2(str1);
cout << wstr2.use_count() << endl;//1,use_count()可以获取强引用的计数
shared_ptr<string> str2(str1);
shared_ptr<string> str3(str1);
cout << wstr2.use_count() << endl;//3,use_count()可以获取强引用的计数
cout << "---------------" << endl;
auto str5 = make_shared<string>("def");
weak_ptr<string> wstr6(str5);
weak_ptr<string> wstr7(str5);
weak_ptr<string> wstr8;
wstr8 = wstr7;//wstr8 = weak_ptr "def" [1 strong ref, 3 weak refs] [make_shared]
wstr8.reset();
// 当wstr8 reset之后,str8为empty
//str7的值是: wstr7 = weak_ptr "def"[1 strong ref, 2 weak refs][make_shared]
cout << "......" << endl;
//lock的使用
if (!wstr7.expired()) {
shared_ptr<string> wstr10 = wstr7.lock();
if (wstr10 != nullptr) {
cout << wstr7.use_count() << endl; // wstr7 = weak_ptr "def" [2 strong ref, 2 weak refs] [make_shared]
}
}
cout << wstr7.use_count() << endl; // 出了作用域后,wstr10的强引用会被-1. 因此wstr7 = weak_ptr "def" [1 strong ref, 2 weak refs] [make_shared]
}
监视 shard_ptr 的生命周期。