这是一篇关于讲解关于shared_ptr使用的问题,在c++11被引入,shared_ptr帮助程序员管理对象的生命周期,内存释放等问题,一定程度上避免了内存泄露
1.Shared_ptr的基本原理:引用计数
在shared_ptr的构造函数(包括拷贝构造和重载赋值拷贝运算符)中,会对use_count进行计数加1,
而在shared_ptr的析构函数中,会对use_count计数减一,当减到0时,会释放只能指针所指向的
内存块(调用被管理对象的析构函数),
2.在以下情况下,会引起Shared_ptr的引用计数加一
- [ ] 当发生赋值拷等贝动作时会引起use_count+1
````c++
#include <iostream>
using namespace std;
class Entry;
Entry e;
class Entry {
public:
explicit Entry() {
Array = new int{ 300 };
}
~Entry() {
std::cout << "Entry的析构函数" << std::endl;
delete Array;
Array = nullptr;
}
int data = 100;
int Array;
};
void func() {
e = new Entry;
std::cout << "智能指针析构之前" << e->Array << std::endl;
std::shared_ptr<Entry> ePoint = make_shared <Entry>(e);
}
int main() {
int a = new int(10);
std::shared_ptr<int> ptr = std::make_shared<int>(a);
std::cout << "shred_ptr的使用次数是" << ptr.use_count() << std::endl; //次数是1
std::shared_ptr<int> ptrAnother1 = ptr;
std::cout << "shred_ptr经过拷贝之后的使用次数是" << ptr.use_count() << std::endl; //次数是2
std::shared_ptr<int> ptrAnother2(ptr);
std::cout << "shred_ptr经过拷贝之后的使用次数是" << ptr.use_count() << std::endl; //次数是3
ptrAnother1.reset(); //释放所有权
std::cout<< "shred_ptr释放一次之后" << ptr.use_count() << std::endl; //次数减一
ptrAnother2.reset(); //释放
std::cout << "shred_ptr释放一次之后" << ptr.use_count() << std::endl; //次数再减一
//当ptr出了main函数之后,ptr的作用域就会完成,同时就会调用所指向对象的析构函数
func();
std::cout << "智能指针析构之后" << *e->Array << std::endl;
return 0;
}
> 上述代码中,在func中将对象e的管理交给智能指针,可以看到,在func调用完之后,自动调用的e对象的析构函数,再次访问时,就不可访问了
## 3.在以下情况下,shared_ptr指向的对象会被销毁
> \- [1] **最后一个剩下的指向该对象的智能指针被销毁时,shared_ptr指向的对象也会被销毁,否则会造成内存泄露**
> \- [2] **最后一个剩下的指向该对象的智能指针在被重新赋值时,shared_ptr指向的对象也会被销毁**
## 4.std::shared_ptr的成员函数
````c++
(构造函数) 构造新的 shared_ptr (公开成员函数)
(析构函数) 如果没有更多 shared_ptr 指向持有的对象,则析构对象 (公开成员函数)
operator= 对 shared_ptr 赋值 (公开成员函数)
reset 替换所管理的对象 (公开成员函数)
swap 交换所管理的对象 (公开成员函数)
get 返回存储的指针 (公开成员函数)
operator*operator-> 解引用存储的指针 (公开成员函数)
operator[] (C++17)提供到被存储数组的带下标访问 (公开成员函数)
use_count 返回 shared_ptr 所指对象的引用计数 (公开成员函数)
unique (C++20 前) 检查所管理对象是否仅由当前 shared_ptr 的实例管理 (公开成员函数)
operator bool 检查是否有关联的管理对象 (公开成员函数)
owner_before 提供基于拥有者的共享指针排序 (公开成员函数)
5.编写如下测试代码
````c++
#include <iostream>
using namespace std;
class Entry {
public:
explicit Entry() {
}
int data = 100;
};
int main() {
Entry a;
std::shared_ptr<Entry> ptr = std::make_shared<Entry>(a);
std::cout << "变量a的地址是" << &a << std::endl;
printf("data address is %p\n", &(a.data));
std::cout << "当前ptr是否唯一指向该对象 " << ptr.unique() << std::endl;
std::cout << "当前ptr是否有所指 " << ptr.operator bool() << std::endl;
ptr.reset(); //释放所有权
std::cout << "当前ptr是否有所指 " << ptr.operator bool() << std::endl;
int number = ptr.use_count(); //0
std::cout << "reset之后use_count的值为 " << number << std::endl;
system("pause");
return 0;
}
## 6.使用shared_ptr应该注意的事项
> -\ [ 1 ] **不能使用一个原始地址初始化多个智能指针,会引起多重析构的问题**
> -\ [ 2 ] **函数不能返回管理了this的共享智能指针对象,也会引起多重析构的问题**