指针 || 引用 || const || 智能指针 || 动态内存

复合类型:

引用:

  1. 基本概念: 绑定对象,不发生拷贝(当普通赋值时,为确保创建新的对象,分配新的地址,对象拷贝操作),相当于对象的别名
  2. 初始化:type & name = obj;
    1. 只能绑定在对象(左值)上,之后所有操作都在绑定的对象进行
    2. 因为一旦绑定了对象,就不能更改,因此定义时必须初始化
    3. 引用非对象:没有 地址 / 内存(数据),因此不能定义引用的引用,也没有const 引用
    4. 初始化时对象类型必须要与引用的类型一致:
      1. 因为类型不一致时,编译器为确保引用绑定相同类型,创建了临时量,我们想要对绑定的对象操作,但目前绑定的只是临时量,不会影响对象本身,所以无法做到我们期望的结果,因此这种行为定义为非法
  3. 赋值:name = val;对引用绑定的对象赋值

指针:

  1. 基本概念:指向对象的地址
  2. 初始化: type * name = &obj取地址;
    1. 定义(分配内存)时不需要初始化(填充数据)
    2. 指针是对象:有自己的内存空间,因此可以定义指针的指针 / 指向指针的引用:type *& name = obj;
    3. 初始化时对象类型必须要与指针的类型一致
  3. 赋值:
  4. 可以改变指针指向的对象(p = &obj || **p = &p2(指向指针的指针) || p = p2(指向同一对象,p2指针作为右值取p2的值)),也可以改变所指向对象的值( *p解引用 = Val)

特殊指针:

  1. 空指针:没有指向任何对象,=nullptr / = 0 / =null(0)(尽量避免使用),试图访问指针指向对象的值,行为不被允许
  2. 无效指针:指向无效内存,试图访问指针指向对象的值,引发错误
  3. void*指针:可以指向任何类型对象, 限制:无法操作所指对象,

技巧:

  1. 如何判断对象类型?从右往左读,右侧优先级更高
  2. 如何判断我们改变了,指针指向的对象 还是 对改变所指向对象的值?赋值永远改变左侧的对象
  3. 同符号有多重含义,如何区分?在定义声明时组成复合类型,在表达式则为取地址/解引用

const常量对象:(非常量->常量 , 常量 !->非常量)

  1. 基本概念:限制变量的值无法改变(防止意外修改)
  2. 初始化:
    1. 定义时必须初始化:const type name = ......
    2. 允许非常量初始化常量
  3. 不允许对常量赋值
  4. 作用域:文件

对const的引用

  1. 与普通引用的区别:
  2. 初始化时,类型不一定要一致,只要可以转换为引用的类型就可以(非const, 字面值,表达式)
  3. 不允许通过引用,改变绑定的对象的值,但并不意味着不能通过其他途经修改(直接给对象赋值(更改数据)/ 绑定到普通引用)

对const的指针:

  1. 与普通指针的区别:
  2. 初始化时,指向的对象类型可以为非const
  3. 不允许通过指针*p=,改变指向的对象的值

const 指针:

  1. 与普通指针的区别:
  2. 定义时必须初始化
  3. 并不能改变指针指向的对象,但允许改变所指对象的值

指向const的const指针:

  1. ·不允许改变指向的对象的值,也不能改变指针指向的对象,
  2. 顶层 / 底层:
    1. 顶层const:本身是常量
    2. 底层const:所指向的对象是常量
    3. 可以即是顶层又是底层
  3. 内存:静态(存放生命周期为整个程序的),堆(保存动态分配的对象),栈(自动的生命周期)

内置指针:

new运算符(手动管理动态内存):

  1. 在堆中分配内存,返回指向该动态分配对象的指针:int * p = new int;'
  2. 初始化对象:对象默认情况为默认初始化,可以用()直接初始化对象的数据
  3. 内存耗尽:用光了堆内存
  4. 释放内存:防止内存耗尽,delete:销毁指向的对象,释放对应的内存。对象的生命周期在被delete前一直存在
  5. 未定义行为 :delete必须释放动态分配 的内存,并且相同的指针值不能释放多次,否则行为将未定义
  6. **空悬指针:**当delete指针,虽热内存释放了,但指针仍保存着无效内存的地址,成为了未初始化的指针(无效指针)
  7. 如何避免空悬指针?重置指针:如果要保留指针,让指针指向nullptr,变为空指针
  8. 但是:当多个指针指向同一内存,重置仅针对这个指针有效

智能指针(自动管理动态内存):

shared_ptr<type> name:(允许多个指针指向同一对象)

  1. 初始化:默认初始化为空指针
  2. 最安全的分配动态内存:= make_shared<name>(val);返回指向,动态分配并初始化未val的对象 ,的shared_ptr.
  3. 引用计数:
    1. 当初始化另一个shared_ptr / 按值传递 / 作为返回值......计数器++;
    2. 当被赋值 / 销毁(例如局部定义的)......计数器 --;
    3. 当计数器 == 0,自动销毁(delete)指向的对象,释放对应的内存。
  4. 作用:适用于多所有者共享对象的场景

shared_ptr&& 普通指针

  1. shared_ptr<type> p(new type(val));:new动态分配返回的指针指向的对象,初始化shared_ptr(必须采用这种直接初始化形式,不能用=拷贝初始化,因为shared_ptr的构造是explicit的,同样作为return也必须显示初始化)
  2. 注意事项:当混合使用new返回的普通指针 *p 和 shared_ptr p 的智能指针,容易引发错误(空悬指针 / 未定义行为):
  3. 当shared_ptr接管了内置指针,可能会无意释放掉内置指针指向的动态分配的内存
  4. 不要用get()初始化智能指针 / 为智能指针赋值:
  5. get()(返回内置指针:指向智能指针管理的对象):当不能使用智能指针时传递内置指针

shared_ptr的其他操作:

  1. shared_ptr<type> p(p1)p是shared_ptr p1的拷贝,指向同一个对象
  2. shared_ptr<type> p(p1)p管理内置指针 p1所指向的对象,p1必须指向new动态分配的内存
  3. shared_ptr<type> p(u)p接管unique_ptr u的对象
  4. reset重置(q可选参数)(相当于内置指针赋值):指向新的对象(内置指针q指向的对象),注意同样会更新引用计数(释放p指向的对象)。当q不存在,会释放(delete)shared_ptr的对象

unique_ptr<type>name;(和普通指针&&shared_ptr都不同(多对一),只能一个unique_ptr独占一个对象(一对一)):

  1. 初始化时必须直接初始化:unique_ptr<type> p(new type(val));
  2. 不支持拷贝/赋值操作,除了可以对将要被销毁的unique_ptr拷贝/赋值操作
  3. 支持转移所有权(从一个unique_ptr到另一个unique_ptr):
    1. release()将指针置为空,并返回内置指针(如果不用来初始化/赋值 智能指针,要记得delete)
    2. reset(q)指向新的对象(指向内置指针q指向的对象)
  4. 当unique_ptr被离开作用域时,指向的对象也被销毁
  5. 作用:适用于独占所有权的场景

weak_ptr:弱的

  1. 初始化:通过shared_ptr初始化(make_shared)
  2. 弱引用:不会增加引用计数
  3. 检查目标是否存在:lock()如果存在返回shared_ptr
  4. 作用:避免shared_ptr可能引发的循环引用问题

为什么使用动态内存?

  1. 不知道需要使用多少对象
  2. 不知道对象需要的准确类型
  3. 在多个对象间共享同一数据(当对象销毁数据不会销毁):shared_ptr:例如对shared_ptr拷贝时,两个指针都指向同一对象
  4. 手动控制对象的生命周期:new
相关推荐
Death2003 分钟前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
六点半8884 分钟前
【C++】速通涉及 “vector” 的经典OJ编程题
开发语言·c++·算法·青少年编程·推荐算法
coduck_S12004zbj31 分钟前
csp-j模拟五补题报告
c++·算法·图论
Death20036 分钟前
Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系
c语言·c++·qt·3d·c#
sukalot1 小时前
windows C++-windows C++-使用任务和 XML HTTP 请求进行连接(二)
c++·windows
qianbo_insist1 小时前
simple c++ 无锁队列
开发语言·c++
zengy51 小时前
Effective C++中文版学习记录(三)
数据结构·c++·学习·stl
MinBadGuy2 小时前
【GeekBand】C++设计模式笔记5_Observer_观察者模式
c++·设计模式
QuantumStack5 小时前
【C++ 真题】B2037 奇偶数判断
数据结构·c++·算法
结衣结衣.6 小时前
C++ 类和对象的初步介绍
java·开发语言·数据结构·c++·笔记·学习·算法