首页 > 其他分享 >learncpp-12 复合类型:引用和指针

learncpp-12 复合类型:引用和指针

时间:2024-07-22 22:31:18浏览次数:11  
标签:12 const string 对象 左值 引用 指针 表达式 learncpp

12 复合类型:引用和指针

12.1 复合数据类型介绍

  • 函数也是一种复合数据类型

12.2 左值和右值

  • 表达式除了可以产生值和副作用,还可以计算为对象或函数
  • C++中的所有表达式都有两个属性:类型值类别
    • 表达式的类型就是计算表达式得出的值、对象、函数的类型
    • 表达式的类型必须在编译时可确定,否则类型检查和类型推导将不起作用
    • 表达式的值可以在编译时确定(如果表达式是constexpr),也可以在运行时确定(如果表达式不是constexpr)
  • 左值表达式和右值表达式
    • 左值表达式的计算结果是一个可识别的对象或函数(可以通过标识符、引用、指针进行访问,并且具有比表达式更长的生存期);右值表达式的计算结果是
    • 左值表达式又分为可以修改的左值表达式和不可修改的左值表达式
    • 右值表达式是不可识别的(这意味着它们必须立即使用),并且只存在于使用它们的表达式的范围内
    • 只有左值表达式可以使用&运算符进行取地址的操作
    • 左值表达式可以隐式转换为右值表达式
      int x{5};
      int y{x};// x is an lvalue expression
      

12.3 左值引用

  • 引用就是现有对象的别名,引用一旦被定义,那么对引用的任何操作都会作用于被引用的对象(引用本质上和被引用的对象相同)
  • 左值引用就是左值(例如一个变量)的别名
  • 通过在类型声明中使用&来声明一个左值引用类型
  • 左值引用变量是一个充当左值(通常是另一个变量)的引用的变量
  • 左值引用必须被初始化
  • 左值引用必须绑定一个可以修改的左值,不能绑定一个不可修改的左值(否则可以通过引用修改这个左值),也不能绑定一个右值
  • void不存在左值引用
  • 引用变量一旦被初始化就不能被改变(不能引用另一个对象)
  • 引用变量遵循和普通变量相同的作用域和生命周期
  • 引用变量的生命周期和被引用变量的生命周期是独立的,哪个先销毁都有可能
  • 当一个对象的引用被销毁时,该对象不会受任何影响
  • 当被引用对象被销毁后,它的引用就称为悬空引用。访问悬空引用会导致未定义的行为
  • 引用不是C++中的对象,引用不需要占用内存
  • 由于引用不是对象,所以不存在引用的引用,因为左值引用必须是一个可识别对象的引用

12.4 const的左值引用

  • 非const左值引用只能绑定一个非const左值;const左值引用可以绑定一个const左值
  • 除非需要修改被引用的对象,否则优先使用const的左值引用,而不是非cosnt的左值引用
  • 非const左值引用不能绑定一个右值;const左值引用可以绑定一个右值(实际上是一个临时对象被创建并用这个右值初始化,然后const左值引用绑定这个临时对象)
  • const左值引用可以绑定不同类型的对象,只要对象的类型可以隐式转换成引用的类型
  • 当一个const左值引用直接绑定到一个临时对象时,临时对象的生存期会被延长以匹配引用的生存期
  • 非const左值引用只能绑定可修改的左值;const左值引用可以绑定可修改左值、不可修改左值、右值
  • constexpr引用只能绑定到全局变量或者静态局部变量(不能绑定到局部变量),因为编译器知道全局变量或者静态局部变量在内存中的实例化地址,因此这些内存地址可以看做是编译时常量
  • 当定义一个const变量的constexpr引用时,需要同时使用constexpr和const

12.5 左值引用传递

  • 使用引用传递可以将实参传递给函数而不是将实参拷贝一份给函数的形参
  • 使用值传递时,改变函数形参不会影响实参的值;而使用引用传递时,改变形参(前提是非const引用)实际上就是在改变实参
  • 因为非const引用只能绑定可修改的左值(或者说非const的变量),所以通过非const引用传递时只能接收可修改的左值作为实参,不能接收const左值和右值

12.6 const左值引用传递

  • 使用const引用传递时,不仅避免了实参的拷贝,还保证了被引用的对象不会被修改
  • 最好使用const引用传递而不是非const引用传递,除非有特殊原因需要修改实参的值
  • class类型的拷贝开销很大,因此一般使用引用传递;基本数据类型的拷贝开销很小,因此一般使用值传递
  • 对于拷贝开销低的对象使用值传递;对于拷贝开销高的对象使用引用传递
  • 优先使用std::string_view传递字符串参数(值传递)而不是const str::string&,除非函数调用了需要C风格字符串或者str::string参数的其他函数

如果实参的类型与形参的类型不匹配,则编译器会尝试隐式转换实参以匹配形参的类型(在这个过程中会创建一个形参类型的临时对象)
创建/拷贝一个std::string_view对象的代价很低,因为不会拷贝它正在查看的字符串
创建/拷贝一个std::string的代价可能很昂贵,因为每个str::string对象都会拷贝一个字符串
因此,std::string_view处理std::stringstd::string_viewC风格字符串这三种实参时开销都不大;而const std::string&只有处理std::string这种实参时开销不大
并且,由于std::string_view是一个普通对象,所以可以直接访问它正在查看的字符串;而const std::string&参数在访问字符串之前需要额外步骤来获取被引用的对象

标签:12,const,string,对象,左值,引用,指针,表达式,learncpp
From: https://www.cnblogs.com/akongogogo/p/18317121

相关文章

  • learncpp-20 函数
    20函数20.1函数指针函数和变量一样,也是在内存中被分配了一块地址。因此,函数指针就是一个保存函数的内存地址的变量函数也是有类型的,例如foo()这个函数的类型就是返回整数且不带参数intfoo(){return5;}<<操作符不知道如何输出函数指针(因为有无数种可能的函数指针),因......
  • learncpp-21 操作符重载
    21操作符重载21.12重载赋值运算符拷贝构造器和拷贝赋值运算符的作用几乎相同,都是将一个对象复制到另一个对象。但是拷贝构造器初始化新的对象,而赋值运算符替换已有对象的内容如果在拷贝前必须创建一个新对象,则使用拷贝构造器(包括按值传递和按值返回)如果在拷贝前无需创......
  • 1323、基于51单片机按键发送GPS时间定位信息 GSM短信收LCD12864显示报警(程序+原理图+
    毕设帮助、开题指导、技术解答(有偿)见文未  目录方案选择单片机的选择一、设计功能二、实物图单片机模块设计三、原理图四、程序源码五、PCB图资料包括:需要完整的资料可以点击下面的名片加下我,找我要资源压缩包的百度网盘下载地址及提取码。方案选择单片机的......
  • learncpp-1 C++基础
    1C++基础1.1语句和程序结构语句是一条让计算机执行某个动作的指令,是C++语言中最小的独立计算单元在高级语言(例如C++)中,一条语句可能编译成多条机器指令大多数语句以;结尾声明语句跳转表达式语句复合语句选择语句(条件语句)迭代语句(循环语句)try代码块函......
  • learncpp-2 函数和文件
    2函数和文件2.9命名冲突和命名空间两个(或多个)同名函数(或全局变量)被引入到属于同一程序的不同文件中,这将导致链接器错误。两个(或多个)同名函数(或全局变量)被引入到同一个文件中。这将导致编译器错误。不同的作用域(例如命名空间)中可以有相同的标识符只有声明和定义可以出现......
  • 12 B端产品常用视图
    原型图        是产品经理最熟悉,也是最常用的,是产品表现层面的Demo,描绘产品的界面长什么样,功能如何设计、摆放,有哪些内容。结构图        展示产品的基本结构、框架,它能清晰展示产品有哪些模块、功能或系统组成。用例图        站在用户的叫做......
  • C语言指针易混淆知识点总结
    指针定义指针是一个变量,存储另一个变量的内存地址,它允许直接访问和操作内存中的数据,使得程序能够以更灵活和高效的方式处理数据和内存。获取变量地址:使用取地址符&。访问地址上的数据:使用解引用符*。例子1指针是存储另一个变量地址的变量。通过使用取地址符&和解引用符......
  • 每日一题-P1251
    网络流24题~#include<bits/stdc++.h>usingnamespacestd;#definelllonglongconstintinf=1e9;constlllnf=1e18;intN,p,m,f,n,s,r[2005],st,ed;structedge{ intv,nx;llw;intc;}e[40005];intcnt,hd[4105];voidadd(intu,intv,llw,intc){ e[++cnt......
  • 我的收藏周刊121
    文章分享Npcapinternalsnpcap,Wireshark在windows下依赖的抓包库实现,其内部抓包实现原理,与unix/linux下的libpcap有所不同,注意这里只是原理介绍,不涉及具体代码,而且代码看起来也没有开源。npcap是winpcap的继承者,winpcap支持到Windows10之前,Windows10及之后的Windows版本只......
  • 《文明6》找不到d3d12.dll怎样处理?文明6游戏启动d3d12.dll丢失解决之道
    在尽情畅玩SidMeier’sCivilizationVI(文明6)这款广受欢迎的策略游戏过程中,部分玩家或许会在启动游戏时碰到提示“d3d12.dll文件丢失”的状况,这给游戏的正常运行带来了严重阻碍。d3d12.dll作为Direct3D12API的核心动态链接库文件,在游戏内的图形渲染与输出方面起着关键作用。本......