关于智能指针类型shared_ptr的计数问题
一、关键
每个shared_ptr所指向的对象都有一个引用计数,它记录了有多少个shared_ptr指向自己
shared_ptr的析构函数:递减它所指向的对象的引用计数,如果引用计数变为0,就会销毁对象并释放相应的内存
引用计数的变化:决定权在shared_ptr,而与对象本身无关
二、引用计数初步
shared_ptr<int> sp; //空智能指针 shared_ptr<int> sp2 = make_shared<int>(3); shared_ptr<int> sp3(sp2); cout << sp.use_count() << endl; //输出0 cout << sp2.use_count() << endl; //输出2
注:sp.use_count()函数返回sp所指对象的引用计数
三、引用计数增加的情况
拷贝一个shared_ptr,其所指对象的引用计数会递增,如:
- 用一个shared_ptr初始化另一个shared_ptr
- 用一个shared_ptr给另一个shared_ptr赋值
- 将shared_ptr作为参数传递给一个函数
- shared_ptr作为函数的返回值
四、引用计数减少的情况
- 给shared_ptr赋予一个新值
- shared_ptr被销毁(如离开作用域)
五、迷途返航
1. 局部的shared_ptr离开其作用域,它所指对象的引用计数会递减(-1)
假设:没有全局的shared_ptr,那么正确的结果应该是该shared_ptr所指的对象被销毁
我之前错误的想法:多个局部shared_ptr共同指向同一个对象,那么该对象的引用计数就>1,该函数结束时对象的引用计数减1(但仍>0),那么该对象不应该被销毁。
纠正想法:既然是多个局部shared_ptr指向该对象,那么函数结束时对象的引用计数就不应该只减1啊!!
shared_ptr<int> init() { shared_ptr<int> sp2 = make_shared<int>(3); shared_ptr<int> sp3(sp2); cout << sp2.use_count() << endl; //输出2 return sp2; //返回sp2,故引用计数递增,变为3 } //sp2和sp3离开作用域,引用计数减2,变为1 int main() { auto p = init(); //此处赋值的拷贝与return处的拷贝是一致的 cout << p.use_count() << endl; //输出1 return 0; }
由代码证实,函数结束时,引用计数减2,而非减1!