1.智能指针的实现原理
智能指针的实现原理就是在一个类的内部封装了类对象的指针,然后在析构函数里对我们的类对象指针进行释放,因为类的析构是在类对象生命期结束时自动调用的,这样我们就省去了手动释放内存的操作,避免忘记手动释放导致的内存泄漏。
2. C++11四种智能指针总结
2.1 auto_ptr:
1.auto_ptr
以前是用在C98中,C++11被抛弃,头文件一般用来作为独占指针
2.auto_ptr
被赋值或者拷贝后,失去对原指针的管理
3.auto_ptr
不能管理数组指针,因为auto_ptr
的内部实现中,析构函数中删除对象使用delete
而不是delete[]
,释放内存的时候仅释放了数组的第一个元素的空间,会造成内存泄漏。
4.auto_ptr
不能作为容器对象,因为STL容器中的元素经常要支持拷贝,赋值等操作。
2.2 unique_ptr:
1.C++11中用来替代auto_ptr
2.拷贝构造和赋值运算符被禁用,不能进行拷贝构造和赋值运算
3.虽然禁用了拷贝构造和赋值运算符,但unique_ptr
可以作为返回值,用于从某个函数中返回动态申请内存的所有权,本质上是移动拷贝,就是使用std:move()
函数,将所有权转移。
2.3 share_ptr:
-
多个指针可以指向相同的对象,调用
release()
计数-1
,计数0
时资源释放 -
.use_count()
查计数 -
.reset()
放弃内部所有权 -
share_ptr
多次引用同一数据会导致内存多次释放 -
循环引用会导致死锁,
-
引用计数不是原子操作。
shared_ptr
有两个数据成员,一个是指向 对象的指针 ptr
,另一个是 ref_count
指针(包含vptr、use_count、weak_count、ptr等);
shared_ptr<Foo> x(new Foo);
shared_ptr<Foo> y = x;
y=x
涉及两个成员的复制,这两步拷贝不会同时(原子)发生,中间步骤 1,复制 ptr 指针,中间步骤 2,复制 ref_count
指针,导致引用计数加 1
步骤一:
步骤二:
因为是两步,如果没有 mutex
保护,那么在多线程里就有数据竞争。
多线程读写同一个 shared_ptr
必须加锁。
2.4 weak_ptr:
1.解决两个share_ptr
互相引用产生死锁,计数永远降不到0,没办法进行资源释放,造成内存泄漏的问题。
2.使用时配合share_ptr
使用,把其中一个share_ptr
更换为weak_ptr
。