C++程序执行顺序疑问:eval调用后析构函数为何未立即执行?
C++临时对象析构时机问题解析
示例代码
#include <iostream> class Obj { public: Obj() { std::cout << "Obj Constructor\n"; } ~Obj() { std::cout << "Obj Destructor\n"; } }; double eval(const Obj fun) { std::cout << "eval fun" << std::endl; return 1.0; } int main() { Obj obj; double res = eval(obj) - eval(obj); std::cout << res << '\n'; return 0; }
程序输出
Obj Constructor eval fun eval fun Obj Destructor Obj Destructor 0 Obj Destructor
疑问
为何第一个eval函数调用后,析构函数并未立即执行?
解答
核心原因是C++中临时对象的析构时机规则:
- 每次调用
eval(const Obj fun)时,因为参数是按值传递,会创建一个Obj类的临时拷贝对象(编译器会生成默认的拷贝构造函数,只是你的代码未打印该过程)。 eval(obj) - eval(obj)是一个完整表达式(即赋值语句右侧的整个运算式),C++标准规定:临时对象的析构动作会延迟到包含它的完整表达式执行完毕时才触发,而非创建它的函数调用结束后立刻执行。- 因此两个
eval调用产生的临时对象,会等到整个减法运算完成、结果赋值给res之后,才会被依次析构——这就是两次eval fun输出后,才连续出现两次Obj Destructor的原因。 - 最后输出
0后,main函数里的局部对象obj会在函数结束时被析构,输出最后一次Obj Destructor。
内容的提问来源于stack exchange,提问作者Rich Gg
相关产品推荐
相关产品推荐

