- 临时对象生命周期变化:
- 当函数按常量引用传递一个临时对象时,临时对象的生命周期会延长至该引用的作用域结束。
- 代码示例:
#include <iostream>
class MyClass {
public:
MyClass() {
std::cout << "MyClass constructor" << std::endl;
}
~MyClass() {
std::cout << "MyClass destructor" << std::endl;
}
};
void func(const MyClass& obj) {
std::cout << "Inside func" << std::endl;
}
int main() {
{
func(MyClass());
std::cout << "After func call" << std::endl;
}
std::cout << "End of main" << std::endl;
return 0;
}
- 在上述代码中,
func(MyClass())
创建了一个临时的 MyClass
对象,并通过常量引用传递给 func
函数。MyClass
的构造函数在 func
函数调用时被调用,输出 MyClass constructor
。
- 由于是通过常量引用传递,临时对象的生命周期延长至
func
函数结束。func
函数结束后,MyClass
的析构函数被调用,输出 MyClass destructor
。然后输出 After func call
,最后输出 End of main
。
- 对程序性能和正确性的影响:
- 性能影响:
- 优点:避免了临时对象的不必要拷贝,提高了性能。例如,如果
MyClass
是一个大对象,拷贝构造函数开销较大,按常量引用传递可以节省这部分开销。
- 缺点:延长临时对象的生命周期可能会增加内存占用时间,特别是在临时对象占用内存较大且作用域较广的情况下。
- 正确性影响:
- 优点:确保在函数使用临时对象的过程中,临时对象不会被提前销毁,保证了程序的正确性。例如,如果函数
func
内部需要访问临时对象的成员变量或调用其成员函数,临时对象生命周期的延长保证了这些操作的合法性。
- 缺点:如果在延长生命周期的作用域内,意外地对常量引用进行了可能导致临时对象被销毁的操作(虽然常量引用本身不能修改对象,但可能通过其他途径导致对象销毁),可能会引发未定义行为。例如,如果在
func
函数内部,通过其他方式删除了 MyClass
对象对应的内存(假设对象在堆上创建,这里只是一种假设情况),而此时临时对象生命周期还未结束,就会导致未定义行为。