一、临时量与临时对象
临时量:
内置类型生成的临时量是常量(临时量,寄存器带出来)。
自定义类型生成的临时量是变量 ,在内存中。
临时对象:
临时对象是系统临时分配的对象,在没主动声明所需对象而又使用其功能时产生的
注意: 临时对象的生存周期只在本条语句。
二、哪些情况产生临时量
2.1 调用构造函数生成的对象
1 | class A |
如果不想让编译器隐式调用构造函数,只需用explicit修饰只需要传一个参数的构造函数。
三、临时变量的引用
3.1 禁止非常量引用
《Effective C++ 第三版》第二十一条规劝,返回对象时,别妄想返回其引用。根源在于:临时对象的生命周期只在本语句。函数返回时,临时变量会被销毁,将引用一个被销毁的对象,这种行为未定义。
在VS2013下测试,函数参数为非常量引用指向临时对象:
1 |
|
上面代码无法编译通过,说明编译器明确指出了这种写法是错误的。错误前置出现在编译期间,较好防范。
在VS2013下测试,函数返回值为非常量引用指向临时对象:
1 |
|
虽然上面代码编译通过了,但是存在潜在风险,程序行为未定义。这种情况尤为注意,因为错误将在运行期出现。其实我好奇的是C++标准为什么不延长这种情况下,临时变量的生命周期。
3.2 常量引用
临时变量是由编译器生成的,C++语言规范没规定编译器生成临时变量的规则,程序员无法得知由编译器生成的临时变量的名字,程序员无法访问那个临时变量。这意味着,以引用的方式传递一个临时变量做为函数参数,如果函数内部对此临时变量做了修改,那么函数返回后,程序员无法获得函数对临时变量的修改。函数对临时变量所做出的所有更改,都将丢失。C++标准为防止给常量或临时变量(只有瞬间的生命周期)赋值(易产生bug),只许使用const引用之。
在VS2013下测试,函数参数为常量引用指向临时对象:
1 |
|
在VS2013下测试,函数返回值为常量引用指向临时对象:
1 |
|
四、优化包含临时对象的程序
- 函数调用传对象时,如果可以,尽量按对象引用来传递,避免构造临时对象
- 函数调用时,按对象引用来传递,如果不需要修改对象,使用const引用,以避免无意修改对象。
- 返回对象时,别妄想返回其引用
- 调用返回对象的函数时,应该以初始化的方式调用,不要以赋值的方式调用,否则会多调用一次构造函数。