auto
编译期推导出变量的类型
注意事项:
1、使用 auto 时要马上初始化
2、auto 不能用作函数的参数
3、在不声明为引用或指针时,auto 会忽略等号右边的引用类型和 const、volatile 属性
4、在声明为引用或指针时,auto 会保留等号右边的引用类型和 const、volatile 属性
5、修饰 lambda
decltype
编译期推导表达式的类型,推导时并不会计算
注意事项:
1、decltype 会保留表达式的引用和 const、volatile 属性
2、如果推导的是表达式/函数调用,那么推导结果与表达式/函数返回值相同
3、如果推导的表达式是左值,返回表达式类型的左值引用;否则返回右值类型
auto 和 decltype 配合
下面的代码中
由于在编译时,t 和 u 还没有定义,所以上面的例子是编不过的,因此解决方案是将返回类型后置
左值、左值引用
左值:等号左边、可取地址
函数名、变量名
返回左值引用的函数调用
前置自增、自减(++i、–i)
赋值运算符连接的表达式(a=b,a+=b等)
解引用表达式 *p
字符串字面值 “abc”
左值引用:对左值的引用
type &name = exp
右值、右值引用
右值:等号右边、不可取地址
右值又分为纯右值和将亡值
1、纯右值
临时变量
除字符串字面值外的字面值
返回非引用类型的函数调用
lambda表达式
后置自增、自减(i++、i–)
算术表达式
2、将亡值
即将要销毁的值,在其他变量不再使用或即将销毁时,空间转移,避免内存空间的分配和释放,相当于延长了变量的生命周期。
将要被移动的对象
T&&函数的返回值
std::move函数的返回值
转换为T&&类型转换函数的返回值
3、右值引用
深浅拷贝和移动语义
C++默认生成的拷贝构造函数是浅拷贝的,如下面的代码
因此可以看到,对象 a 和 b 的指针成员变量指向的是同一块内存空间,仅仅只是做了简单的复制,所以在 func 函数调用结束的时候,对象 a 和 b 的析构函数会被调用,也就是同一块内存空间被析构了两次,于是我们 main 函数中的 。。。没有被打印出来。
所以,解决的办法是自己实现拷贝构造函数,并且是重新分配一块内存空间,以实现深拷贝