C++11,智能指针详解,以及面试常见问题

本文详细介绍了C++11中的智能指针,包括unique_ptr、shared_ptr和weak_ptr的使用和特性。重点讨论了智能指针如何防止内存泄漏,以及在面试中常被问到的shared_ptr的内存泄露问题及其解决方案——weak_ptr。通过示例,解释了循环引用导致的内存泄漏和如何利用weak_ptr解决这一问题。
摘要由CSDN通过智能技术生成

1.为什么要使用智能指针:

智能指针的作用是管理一个指针,因为使用裸指针存在以下这种情况:申请的空间在函数结束时忘记释放,造成内存泄漏(还存在delete之后没有置为nullptr,造成指针悬空野指针),使用智能指针可以很大程度上的避免这个问题,本质上智能指针就是一个类模板, 当超出了智能指针的作用域时,类会自动调用析构函数,析构函数会自动释放资源。所以智能指针的作用原理就是在析构函数中自动释放内存空间,不需要手动释放内存空间。智能指针是RAII机制的一种体现。

四种智能指针:
auto_ptr(c++98 提出,c++11 废弃,建议直接不学)。
   int main(int argc , char * argv[])
   {
   
       std::auto_ptr<int> p1(new int(10));
       std::auto_ptr<int> p2;
       p2 = p1; // auto_ptr是所有权机制
       std::cout<<*p2<<std::endl; // 10 
       std::cout<<*p1<<std::endl; // 段错误
       return 0;
   }

语法检测不会报错,p2剥夺了p1 的所有权,当程序运行时访问p1 将会报错。

auto_ptr 的缺点是:存在潜在的内存崩溃问题


unique_ptr(auto_ptr的优化)

unique_ptr 实现独占式拥有,保证同一时间内只有一个智能指针可以指向该对象。它对于避免内存泄露(例如“以new创建对象后因为发生异常而忘记调用delete”)特别有用。

unique_ptr采用所有权模式,还是上面那个例子

   int main(int argc , char * argv[])
   {
   
       std::unique_ptr<int> p1(new int(10));
       std::unique_ptr<int> p2;
       // p2 = p1; 报错,非法操作
       return 0;
   }

编译器会认为p2=p1是非法操作,这样就避免了p1不再指向有效数据的问题。因此,unique_ptr比auto_ptr更安全。

另外 unique_ptr 还有更灵活的地方:当程序试图将一个 unique_ptr 赋值给另一个时,如果源unique_ptr 是个临时右值,编译器允许这么做;如果源 unique_ptr 将存在一段时间,编译器将禁止这么做,比如:

   unique_ptr<int> p1(new int (12)); 
   unique_ptr<int> p2;
   p2 = p1;	//#1 不允许,因为p1将存在一段时间,p1是个左值
   
   unique_ptr<int> p3;
   p3 = unique_ptr<int>(new int(8));	//#2 允许,等号右边是临时右值

其中#1 会留下悬挂的p1,这可能导致危害(类似auto_ptr)。而#2 不会留下悬挂的 unique_ptr, 因为它调用 unique_ptr 的构造函数,该构造函数创建的临时对象在其所有权让给 p3 后就会被销毁。这种随情况而定的行为表明,unique_ptr 优于允许两种赋值的auto_ptr 。

注:如果确实想执行类似于#1 的操作,要安全的重用这种指针,可给它赋新值。C++有一个标准库函数std::move(),让你能够将一个 unique_ptr 赋给另一个。例如:

   int main(int argc , char * argv[])
   {
   
       std::unique_ptr<int> p1, p2; 
       p1 = std::make_unique<int>(10);
       p2 = std::move(p1);
       p1 = std
  • 24
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

huafeng88

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值