假设我有以下snipplet:
Foo foo;
....
return bar();
现在,C ++标准是否保证在foo :: ~Foo()之前调用bar()?或者这是编译器/实现的选择吗?
谢谢!
答案 0 :(得分:15)
保证行为。实际执行按如下方式展开:
0: enter block (scope)
1: Foo::Foo()
2. evaluation of bar(); as expression in return statement
3. save result of the expression as value returned from function
4. finalize return statement to leave function to its caller (request exit from current scope)
5: exit block (scope) with call to Foo::~Foo()
以下是该标准的一些参考资料:
1.9程序执行
10具有自动存储持续时间(3.7.2)的每个对象的实例是 与每个条目相关联 块。
foo
具有自动存储持续时间,并且:3.7.2自动存储持续时间
1显式声明自动或注册或未显式声明的本地对象 static或extern具有自动存储持续时间。存储 这些对象会持续到创建它们的块为止。
6.6.3退货声明
2(...)表达式的值返回给函数的调用者
和
6.6跳转语句(返回属于跳转语句)
2退出范围(无论多么完成)时,将为所有人调用析构函数(12.4) 具有自动存储持续时间的构造对象(3.7.2)
6.7声明声明
2块中声明的具有自动存储持续时间的变量是 从街区退出时被摧毁
和
12.4析构函数
对于构造的,隐式调用10个析构函数(1) 静态存储持续时间的对象 (3.7.1)程序终止时 (3.6.3),(2)对于构造对象 具有自动存储持续时间 (3.7.2)当其中的块 对象创建出口(6.7)
要掌握分散在所有C ++标准中的单一构思表单细节并不容易。希望快速概述也可以帮助您自己进行此类分析。
答案 1 :(得分:7)
是的,bar()将在foo的析构函数之前调用。
标准说: 6.6:“退出范围(无论多么完成),析构函数(12.4)是 调用具有自动存储持续时间的所有构造对象 (3.7.2)在该范围内声明的(命名对象或临时对象), 按照他们声明的相反顺序。“
在返回语句完成之前,不会留下范围。
答案 2 :(得分:5)
调用bar()的结果必须在包含Foo的堆栈帧被清除之前进行评估,所以是的,bar()将在Foo :: ~Foo()之前调用。
答案 3 :(得分:3)
对象在离开范围时会破坏。
return
离开范围,但在执行bar()
之前无法返回。 Ergo,bar()
被称为。
答案 4 :(得分:2)
试想一下,如果是return bar(foo);
怎么办?只是有才能工作,如果销毁顺序不同,那将是愚蠢的,这取决于你是否将其作为参数传递。