Mic*_*zek 22 c++ memory-management specifications
是一个临时创建的函数调用参数的一部分,保证在调用函数结束前保持不变,即使临时函数没有直接传递给函数?
几乎没有机会是连贯的,所以这是一个例子:
class A {
public:
A(int x) : x(x) {printf("Constructed A(%d)\n", x);}
~A() {printf("Destroyed A\n");}
int x;
int* y() {return &x;}
};
void foo(int* bar) {
printf("foo(): %d\n", *bar);
}
int main(int argc, char** argv) {
foo(A(4).y());
}
Run Code Online (Sandbox Code Playgroud)
如果A(4)直接传递给foo它肯定不会在foo调用结束后销毁,而是我在临时调用一个方法并丢失对它的任何引用.我会本能地认为临时A会在foo开始之前被销毁,但是用GCC 4.3.4测试表明它不是; 输出是:
构造A(4)
foo():4
毁灭A
问题是,GCC的行为是否符合规范?或者是一个编译器允许A在调用之前销毁临时文件foo,使指向我正在使用的成员的指针无效?
Jam*_*lis 20
临时对象一直存在,直到创建它们的完整表达式结束.
在您的示例中,A创建的对象A(4)将至少存在,直到表达式从调用返回后结束foo().
语言标准保证了这种行为:
临时对象作为评估全表达式(1.9)的最后一步被销毁,该表达式(词法上)包含创建它们的点.即使该评估以抛出异常结束也是如此(C++03§12.2/ 3).
临时的生命周期可以通过绑定对它的引用来扩展(在这种情况下,它的生命周期延长到引用的生命周期结束),或者通过在构造函数的初始化列表中使用它作为初始化器(在这种情况下,寿命延长,直到构造的对象完全构造).