当前位置: 首页 > news >正文

c++智能指针

在c++里边对于内存的管理是需要程序员自己手动释放的,那为什么不像Java那样弄一个自动回收垃圾的东西呢?秉承着存在即合理的原则,c++存在没有垃圾回收这样的玩意,那肯定是为了它的运行效率,在算法竞赛中,一般c/c++时间要求是最短的。
扯远了,所以你在Java中是听不到谁在说什么智能指针的,还得是我们c++呀,c++玩家太有操作了。对于智能指针这种东西其实他是遵顼一种RAII的思想设计的。


RAII(Resource Acquisition Is Initialization):是一种利用对象生命周期来控制程序资源(如内
存、文件句柄、网络连接、互斥量等等)的简单技术。
在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在
对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做
法有两大好处:
1.不需要显式地释放资源。
2.采用这种方式,对象所需的资源在其生命期内始终保持有效
 

在c++里边有四种关于智能指针的类,其中一种不是完全用来管理内存的,一种是不学跟学了一样(一般用不到的),后面两种只有学起来要深入些。
 

1.auto_ptr

这是c98推出的一个智能指针,类似于这种思想
 

template<class T>
class auto_ptr
{
public:auto_ptr(T* ptr):_ptr(ptr){}auto_ptr(auto_ptr<T>& sp):_ptr(sp._ptr){// 管理权转移sp._ptr = nullptr;}auto_ptr<T>& operator=(auto_ptr<T>& ap){// 检测是否为自己给自己赋值if (this != &ap){// 释放当前对象中资源if (_ptr)delete _ptr;// 转移ap中资源到当前对象中_ptr = ap._ptr;ap._ptr = NULL;}return *this;}~auto_ptr(){if (_ptr){cout << "delete:" << _ptr << endl;delete }}// 像指针一样使用T& operator*(){return *_ptr;}T* operator->(){return _ptr;}private:T* _ptr;};

这就是那个没学跟学了一样的智能指针。官方文档也自个都说了不推荐使用这个智能指针。

这类指针它支持拷贝,但是不完全支持,它的拷贝只能说是鸡肋。

应为它拷贝完之后会将b1内容清空。
所以官方让我们去用unique_ptr。

2.unique_ptr

见名知意就是不准你拷贝


直接会给你报错,其实就是将拷贝给delete了,简单的实现非常简单,就不cv过来了。

3.shared_ptr

C++11中开始提供更靠谱的并且支持拷贝的shared_ptr
shared_ptr的原理:是通过引用计数的方式来实现多个shared_ptr对象之间共享资源。例如:
比特老师晚上在下班之前都会通知,让最后走的学生记得把门锁下。
1. shared_ptr在其内部,给每个资源都维护了着一份计数,用来记录该份资源被几个对象共享。
2. 在对象被销毁时(也就是析构函数调用),就说明自己不使用该资源了,对象的引用计数减一。
3. 如果引用计数是0,就说明自己是最后一个使用该资源的对象,必须释放该资源;
4. 如果不是0,就说明除了自己还有其他对象在使用该份资源,不能释放该资源,否则其他对象就成野指针了。

这个才是最常用的,但是得注意一下循环引用。

举个循环引用的栗子:


struct ListNode
{int _data;shared_ptr<ListNode> _next;shared_ptr<ListNode> _prev;~ListNode(){cout << "~ListNode()" << endl;}
};void test3()
{shared_ptr<ListNode> n1(new ListNode);shared_ptr<ListNode> n2(new ListNode);n1->_next = n2;n2->_prev = n1;
}


这样就会出现内存泄漏,这时候我们需要weak_ptr来管理,应为weak_ptr不增加引用计数


http://www.mrgr.cn/news/24800.html

相关文章:

  • 天线方向 面试/笔试题 汇总
  • 2. 变量和指令(omron 机器自动化控制器)——2
  • chfsgui局域网共享局域网http服务 Cute HTTp File Server软件
  • 【白话Redis】缓存雪崩、穿透、击穿、失效和热点缓存重建
  • 使用QT界面运行roslaunch,roslaunch,roscore等
  • 常见 HTTP 状态码详解与Nginx 文件上传大小限制
  • C语言深入理解指针五(18)
  • 杂七杂八-必备软件下载
  • redis底层—网络模型
  • tcp、http和rpc
  • MyBatis快速入门
  • numpy(基于Numpy外文文档的学习)
  • 品读 Java 经典巨著《Effective Java》90条编程法则,第2条:遇到多个构造器参数时要考虑使用构建器
  • 1,修改图片后缀名 2,重新按顺序重命名图片 python实测有效
  • 基于SpringBoot+Vue+MySQL的实训管理系统
  • C++ 互斥锁、条件变量的基础使用
  • 初始Linux 和 各种常见指令
  • 杀毒软件 | Malware Hunter v1.189.0.816 绿色版
  • 算法知识点————背包问题【动态规划】【打家劫舍】
  • 文件IO编程