复制构造函数?

时间:2010-02-24 20:49:48

标签: c++

  

可能重复:
  Why copy constructor is not called in this case?

当您通过值将对象传递给函数或通过值从函数返回对象时,必须调用复制构造函数。但是,在某些编译器中,这不会发生?有什么解释吗?

3 个答案:

答案 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对象的任何开销。