C++语法知识(21-40)

1. 省略号(…)用法

c++中的省略号

1. 变参函数

变参函数的深度解析(通俗易懂)

2. 变参模板类–C++11新特性

省略号和可变参数模板

3. 变参模板函数–C++11新特性

C++模板(第二版)笔记之第四章:变参模板
c++11增加的变参数模板,今天总算整明白了
C++11:变参函数模板、变参类模板、模板模板参数

4. 变参宏

可变参数宏
C/C++ #运算符、##运算符、变参宏 …和_ VA_ARGS _

5. 折叠表达式

C++17之折叠表达式
跟我学c++中级篇——c++17中的折叠表达式

2. goto语句

c++关键字goto

3. C语言内存操作函数

memcpy()

【C语言】memcpy()函数(内存块拷贝函数)

4. std::is_same()判断两个类型是否相同

C++ 语言 std::is_same

5. decltype关键字

【C++深陷】之“decltype”

6. 左值、右值及其引用

左值和右值定义

网上关于左值、右值介绍的文章有很多,大多数文章都通过表达式能够出现在赋值号=的左、右来定义左右值,这样的定义对于读者不好理解,也没有表达出左右值的真实区别和意义。
文章C++左值(引用)和右值(引用)详解关于左右值的定义如下:
左值:在内存有确定存储地址、有变量名,表达式结束依然存在的值,简单来说左值就是非临时对象。
右值:就是在内存没有确定存储地址、没有变量名,表达式结束就会销毁的值,简单来说右值就是临时对象。

int a = 0;  // 在这条语句中,a 是左值,0 是临时值,就是右值。

该定义从对象的临时性角度定义左右值,能够表达出左右值的真实区别和存在的意义。

左值可以分为两类:非常量左值和常量左值;

int a=10;              	// a 为非常量左值(有确定存储地址,也有变量名)
const int a1=10;      //a1 为常量左值(有确定存储地址,也有变量名)
const int a2=20;      //a2 为常量左值(有确定存储地址,也有变量名)

同理,右值也可以分为两类:非常量右值和常量右值。

int a=10;              	// 10 为常量右值 (原文中说这事非常量右值,应该正好写反了)
const int a1=10;      
const int a2=20;      
a1+a2               	// (a1+a2) 为非常量右值

左值引用和右值引用

左值引用:其实就是绑定到左值的引用,通过&来获得左值引用;

int a=10;              //非常量左值(有确定存储地址,也有变量名)
const int a1=10;       //常量左值(有确定存储地址,也有变量名)
const int a2=20;       //常量左值(有确定存储地址,也有变量名)
 
//非常量左值引用
int &b1=a;            //正确,a是一个非常量左值,可以被非常量左值引用绑定
int &b2=a1;           //错误,a1是一个常量左值,不可以被非常量左值引用绑定
int &b3=10;           //错误,10是一个常量右值,不可以被非常量左值引用绑定
int &b4=a1+a2;        //错误,(a1+a2)是一个非常量右值,不可以被非常量左值引用绑定

//常量左值引用
const int &c1=a;      //正确,a是一个非常量左值,可以被非常量右值引用绑定
const int &c2=a1;     //正确,a1是一个常量左值,可以被非常量右值引用绑定
const int &c3=a+a1;   //正确,(a+a1)是一个常量右值,可以被常量右值引用绑定
const int &c4=a1+a2;  //正确,(a1+a2)是一个非常量右值,可以被非常量右值引用绑定

总结:非常量左值引用只能绑定到非常量左值上;常量左值引用可以绑定到非常量左值、常量左值、非常量右值、常量右值等所有的值类型。

右值引用:其实也是绑定到右值的引用,通过&&(中间无空格)来获得右值引用。

int a=10;             //非常量左值(有确定存储地址,也有变量名)
const int a1=20;      //常量左值(有确定存储地址,也有变量名)
const int a2=20;      //常量左值(有确定存储地址,也有变量名)

//非常量右值引用
int &&b1=a;            //错误,a是一个非常量左值,不可以被非常量右值引用绑定
int &&b2=a1;           //错误,a1是一个常量左值,不可以被非常量右值引用绑定
int &&b3=10;           //正确,10是一个非常量右值,可以被非常量右值引用绑定
int &&b4=a1+a2;        //错误,(a1+a2)是一个常量右值,不可以被非常量右值引用绑定

//常量右值引用
const int &&c1=a;      //错误,a是一个非常量左值,不可以被常量右值引用绑定
const int &&c2=a1;     //错误,a1是一个常量左值,不可以被常量右值引用绑定
const int &&c3=a+a1;   //正确,(a+a1)是一个非常量右值,可以被常量右值引用绑定
const int &&c4=a1+a2;  //正确,(a1+a2)是一个常量右值,不可以被常量右值引用绑定

总结:非常量右值引用只能绑定到非常量右值上;常量右值引用可以绑定到非常量右值、常量右值上。

从上述可以发现,常量左值引用可以绑定到右值上,但右值引用不能绑定任何类型的左值,若想利用右值引用绑定左值该怎么办呢?
C++11中提供了一个标准库move函数获得绑定到左值上的右值引用,即直接调用std::move告诉编译器将左值像对待同类型右值一样处理,但是被调用后的左值将不能再被使用。
std::move()函数举例:

int a=10;                 //非常量左值(有确定存储地址,也有变量名)
const int a1=20;          //常量左值(有确定存储地址,也有变量名)

//非常量右值引用
int &&d1=std::move(a);    //正确,将非常量左值a转换为非常量右值,可以被非常量右值引用绑定
int &&d2=std::move(a1);    //错误,将常量左值a1转换为常量右值,不可以被非常量右值引用绑定

//常量右值引用
const int &&c1=std::move(a);      //正确,将非常量左值a转换为非常量右值,可以被常量右值引用绑定
const int &&c2=std::move(a1);     //正确,将常量左值a1转换为常量右值,可以被常量右值引用绑定

最后可以发现,编译器利用std::move将左值强制转换为相同类型的右值之后,引用情况跟右值是一模一样的。

C++11引入右值引用的目的?

1、替代需要销毁对象的拷贝,提高效率:某些情况下,需要拷贝一个对象然后将其销毁,如:临时类对象的拷贝就要先将旧内存的资源拷贝到新内存,然后释放旧内存,引入右值引用后,就可以让新对象直接使用旧内存并且销毁原对象,这样就减少了内存和运算资源的使用,从而提高了运行效率;

2、移动含有不能共享资源的类对象:像IO、unique_ptr这样的类包含不能被共享的资源(如:IO缓冲、指针),因此,这些类对象不能拷贝但可以移动。这种情况,需要先调用std::move将左值强制转换为右值,再进行右值引用。

简单介绍:左值引用和右值引用
【重点看:引入右值引用、移动拷贝、移动赋值函数后减少对象拷贝的介绍】:左值引用、右值引用详解
待看:左值引用和右值引用
待看:【C++深陷】之“左值与右值”

7. 获取系统时间

如何在 C++ 中以毫秒为单位获取时间

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值