C++ 在callsite参数处创建的临时对象的生命范围
我有下面的代码,我想知道什么时候调用Foo的析构函数C++ 在callsite参数处创建的临时对象的生命范围,c++,C++,我有下面的代码,我想知道什么时候调用Foo的析构函数 #include <iostream> class Foo { public: Foo() { } ~Foo() { std::cout << "destruct" << std::endl; } }; void go(Foo f) { std::cout << "go" << std::endl; } int main() { go(Foo()
#include <iostream>
class Foo {
public:
Foo() {
}
~Foo() {
std::cout << "destruct" << std::endl;
}
};
void go(Foo f) {
std::cout << "go" << std::endl;
}
int main() {
go(Foo());
std::cout << "main" << std::endl;
return 0;
}
它显示在go完成后调用Foo的析构函数。我的gcc是4.8.3
我原以为临时Foo的对象在复制到go的参数后应该被删除。但事实并非如此,Foo只存在一个对象。在编译器的实现中,这是预期的还是未定义的? 它是C++标准允许的优化。 < C++标准草案,我和我引用(相关部分,重点是我的): 临时对象的物化通常会延迟 尽可能避免创建不必要的临时对象。 例如:
class X {
public:
X(int);
X(const X&);
X& operator=(const X&);
~X();
};
class Y {
public:
Y(int);
Y(Y&&);
~Y();
};
X f(X);
Y g(Y);
void h() {
X a(1);
X b = f(X(2));
Y c = g(Y(3));
a = f(a);
}
X(2)
构造在用于容纳f()
的参数和
Y(3)
构造在用于容纳g()
的参数的空间中
以前,在年,它说:
一个实现可能会使用一个临时变量来构造X(2)
在使用X
的复制构造函数将其传递给f()
之前;
或者,X(2)
可以构建在用于容纳
论据
这意味着:
void go(Foo) {
std::cout << "go" << std::endl;
}
int main() {
go(Foo());
}
总之,
在本例中,如果不使用std::move
,则会创建一次对象,如图所示
但是当您使用std::move
时,它会被创建两次,这是因为对象的物化。阅读的完整段落,了解物化的含义
go
使用Foo
,为什么要在go
使用它之前将其删除?一个真正愚蠢的编译器可以创建一个临时文件,然后将其复制到参数中并删除临时文件,但是如果您所做的只是立即删除它,那么创建临时文件的意义何在?
void go(Foo) {
std::cout << "go" << std::endl;
}
int main() {
go(Foo());
}
void go(Foo) {
std::cout << "go" << std::endl;
}
int main() {
go(std::move(Foo()));
}