C++中的普通变量,指针,引用,智能指针

普通变量/对象

储存位置:栈

当定义一个变量的时候,计算机会将指定的一块内存空间和变量名进行绑定,如:

int a = 1;

此时便会申请一块内存空间,里面储存着值1,可以看作这块内存空间的名字是a。

  • 优点:直接的值传递;
  • 缺点:占用大量内存空间,在定义或传递一些内存占用较大的变量(如结构体等)甚至能耗尽栈空间。

在c++中,通过直接定义普通变量或对象并不能满足所有的需求,很多时候我们需要用到指针,引用等其他方式。

 

指针

储存位置:堆

指针是一种储存地址的变量,其内存空间里存放的不是具体的值,而是某个变量的地址,如:

int a = 1;
int *ptr = &a;

 其中 &取地址符,取得a变量对应的内存空间的地址,有了这个地址,便可以找到变量a所在的内存空间,进而获取变量a储存的值。

指针的优点

  • 通过Object myObject 方式定义对象会消耗大量内存,而用指针做形参。指针的空间占用是与CPU的寻址长度相关的,如果是32位的话就是4个字节,大大减少了内存的占用;
  • 可以实现多态;
  • 动态内存分配的便利性;

指针的缺点

  • 指针涉及到手动的内存管理和释放,通过 new Object() 方式分配对象时,对象的生存期是动态的,这意味着若不显式地 detete 对象,对象将一直存在。
  • 潜在的内存冲突(数组越界)和内存泄漏;
  • 空指针和野指针的存在可能会导致程序崩溃。

 

引用

首先明确一点,引用本质上也是指针,属于一种特殊的指针。在c++中,最开始引用的引入是为了支持运算符重载。既然C++引入了引用,那为什么C++不和Java一样抛弃指针呢?答案是为了兼容C语言。

引用就是变量的别名,指向同一个内存地址,直接对引用的修改都会改变引用所指向的对象。

引用的优点:

  • 使用引用的时候会自动解引用,而不需要像使用指针一样显式解引用;
  • 不存在空引用(保证不操作空指针);
  • 必须初始化(保证不是野指针);
  • 一个引用永远指向他初始化的那个对象(保证指针值不变);

引用的缺点:

  • 指针在使用中可以指向其它对象,但是引用只能是一个对象的引用;
  • 指针可以有多级指针(**p),而引用只能一级。

 

智能指针

储存位置:栈

为了更加容易(更加安全)的使用动态内存,引入了智能指针的概念。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。

智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类是栈上的对象,智能指针指向堆上开辟的空间,函数结束时,栈上的函数会自动被释放,智能指针指向的内存也会随之消失,防止内存泄漏。其包含在头文件<memory>中,其中包括:

  • shared_ptr:它采用引用计数的方法,记录当前内存资源被多少个智能指针引用,该引用计数的内存在堆上分配。每新增一个引用计数加1,当过期时引用计数减1。只有引用计数为0时,智能指针才会自动释放引用的内存资源。shared_ptr的一个最大的陷阱是循环引用,会导致堆内存无法正确释放,从而导致内存泄漏。
  • weak_ptr:为了解决循环引用导致的内存泄漏,引入了weak_ptr弱指针,weak_ptr的构造函数不会修改引用计数的值,从而不会对对象的内存进行管理,其类似一个普通指针,虽然不指向引用计数的共享内存,但是可以检测所管理的对象是否已经被释放,从而避免非法访问。
  • unique_ptr:一种对资源具有独占性的智能指针,即一个对象资源只能同时被一个unique_ptr指向。

 

总结使用场景

1.引用和指针

  • 指针尽可能得以引用代替,除却一些引用无能为力的场景,如指针在使用中可以指向其它对象,而引用不行;

2.智能指针和指针

  • 智能指针天生负责对象生命期管理;所以生命期对象全都由unique_ptr和shared_ptr来管理。
  • 原始指针天生不负责对象生命周期管理;所以使用动态对象均通过原始指针来使用(参考各种第三方库QT/BCG/OS API等等)。

 

 

参考:https://www.zhihu.com/question/319277442

   https://www.csdn.net/gather_26/MtzaUgwsMjgtYmxvZwO0O0OO0O0O.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值