2021-11-03 C++智能指针

1、为什么要引入智能指针?
C++的智能指针是为了处理直接申请动态内存导致的内存问题的产物。所以引入智能指针,其保证在作用域结束时调用析构函数销毁对象,释放内存。关于析构函数的作用,也是为了删除动态申请的内存。这个时候只要把delete放在析构函数里,就会自动被调用。
使用智能指针,可以避免同一块内存被释放两次等会使程序崩溃的情况发生。而为什么同一块内存被释放两次呢,这是因为C++中类的默认构造函数默认是浅拷贝,浅拷贝是指并不再为新类的变量开辟空间,尤其是指动态分配的内存,而是直接使用指针指向原来相同的那一部分内存,所以会导致同一块内存被释放两次。
使用新定义的拷贝构造函数后,实现指针所有权转移,可以避免上述问题。这就是auto_ptr的由来。
2、深拷贝和浅拷贝的区别?
深拷贝在复制时不但对指针进行复制,而且也复制指针指向的内存。而浅拷贝只复制指针变量。
当我们new了一个对象,并把它赋值给对象中的一个指针时,这个指针指向该对象。而当新建一个对象后,用原对象对他进行默认构造函数的赋值,此时新对象的指针,指向的是原对象的指针指向的那块内存,意思就是两个指针指向同一块内存。
3、什么是auto_ptr?
auto_ptr是C++03中为了解决内存多次释放等问题而出现的产物。它的=操作符,以及拷贝构造函数都是进行移动构造的。

#include <memory>
int main()
{
    //初始化方式1
      std::auto_ptr<int> sp1(new int(8));
    //初始化方式2
     std::auto_ptr<int> sp2;
     sp2.reset(new int(8));
     return 0;
}

所以应当避免在STL容器中使用auto_ptr,因为算法中一定会使用到=,而引发出乎意料的错误。
4、什么是unique_ptr?
为了解决auto_ptr的问题,C++11一共引入了unique_ptr/shared_ptr/weak_ptr三种新型智能指针。

#include<memory>
int main(){
	std::unique_ptr<int> uptr(new int(10));//初始化方式1
	uptr.reset(new int(10));//方式2
	std::unique_ptr<int> uptr=std::make_unique<int>(123);//方式3
}

鉴于auto_ptr的问题,unique_ptr禁用复制语义。它将=赋值运算符和拷贝构造函数都置为delete。
但禁止语义也存在特例,可以通过一个函数来返回unique_ptr。
那么如何将unique_ptr的内存进行转移呢?答案是使用std::move(uptr)。
unique_ptr的特点可以总结如下:
(1)指向的内存只能同时被一个unique_ptr所持有,引用计数最大值为1.
(2)它不能狗进行赋值运算符和拷贝构造
(3)它的存在随着作用域的结束将被销毁,而调用析构函数后内存自然被释放。
5、什么是shared_ptr?
unique_ptr只能独占内存,不能共享内存。所以需要有可以共享内存的shared_ptr出现。

#include<iostream>
#include<memory>


int main() {
    std::shared_ptr<int>uptr = std::make_shared<int>(10);
    std::shared_ptr<int>uptr1(uptr);
    std::cout << uptr1.use_count()<<std::endl<<*uptr1<<std::endl;//返回2  10
    std::cout<<uptr1.get();//返回uptr1的地址
    std::cout << uptr.get();//返回uptr的地址  获取指针
    return 0;
}

shared_ptr依然是出作用域时执行析构。
智能指针具有循环引用问题:比如我们在类中定义一个共享指针,并且在main函数中也定义一个指向类的对象的共享指针。这时如果类中有一个指向share_from_this()即当前对象的this共享指针,将会造成循环引用。循环引用使内存无法正常释放。这种情况下使用了智能指针也造成了内存泄漏。
但是我的怎么不可以用啊enable_shared_from_this。

#include<iostream>
#include<memory>

class A:public std::enable_shared_from_this<A> {
public:
    A(){}
    ~A(){}
private:
    std::shared_ptr<A>uptr_m = shared_from_this();

};
int main() {
    std::shared_ptr<int>uptr = std::make_shared<int>(10);
    
    return 0;
}

还是就记两个共享指针相互指向吧。
6、什么是weak_ptr?
弱指针对资源的访问权限有限。因为没有重载->和*,所以无法直接操作对象。另外weak_ptr也没有重写!操作符,所以无法使用!wptr判断弱指针是否为空。弱指针适合那些能够使用就使用,不能使用就不用的场景,不需要管理对象生命周期的场景。比如订阅者模式或者观察者模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值