当您通过值将对象传递给函数或通过值从函数返回对象时,必须调用复制构造函数。但是,在某些编译器中,这不会发生?有什么解释吗?
答案 0 :(得分:5)
我认为它们指的是在许多编译器中实现的返回值优化,其中代码为:
CThing DoSomething();
变成了
void DoSomething(CThing& thing);
将事物在堆栈中声明并传递给DoSomething:
CThing thing;
DoSomething(thing);
可防止需要复制CThing。
答案 1 :(得分:5)
它通常不会发生,因为它不需要发生。这称为复制省略。在许多情况下,该函数不需要复制,因此编译器会将它们优化掉。例如,使用以下函数:
big_type foo(big_type bar)
{
return bar + 1;
}
big_type a = foo(b);
将转换为:
void foo(const big_type& bar, big_type& out)
{
out = bar + 1;
}
big_type a;
foo(b, a);
删除返回值称为“返回值优化”(RVO),并且由大多数编译器实现,即使关闭优化也是如此!
答案 2 :(得分:1)
编译器可以调用复制构造函数来传递值或按值返回,但它不必。该标准允许将其优化(在标准中称为 copy elision )并且实际上许多编译器都会这样做,即使您没有打开优化。解释非常详细,所以我会指出C++ FAQ LITE。
简短版本:
struct Foo
{
int a, b;
Foo(int A, int B) : a(A), b(B) {}
};
Foo make_me_a_foo(int x)
{
// ...blah, blah blah...
return Foo(x, x+1); // (1)
}
Foo bar = make_me_a_foo(42); // (2)
这里的技巧是允许编译器直接在第(1)行中从第(2)行构造bar
,而不会产生构造临时Foo
对象的任何开销。