将新创建的对象传递给函数时是否可以避免复制构造函数?

时间:2014-12-07 15:55:22

标签: c++ copy-constructor

我想弄清楚是否可以避免在将刚刚创建的对象传递给函数时调用copy-constructor?我不想再使用这个对象,我只想命名临时文件并将其按值传递给其他函数。

我知道在C ++ 11中我可以移动这个对象,但我关注如何在C ++ 03中改进它。基本上,我有兴趣在下面的代码中消除copy-constructor调用:

段:

#include <iostream>

struct Foo
{
    Foo(void) { std::cout << "Default ctr\n"; };
    Foo(const Foo& f) { std::cout << "Copy ctr\n"; }
};

void bar(Foo f)
{
    std::cout << "Inside bar\n";
}

int main()
{
    Foo f;
    bar(f);
    bar(Foo());
}

可能的结果:

Default ctr
Copy ctr
Inside bar
Default ctr
Inside bar

编译字符串:

g++ -O3 -Wall -pedantic main.cpp && ./a.out

即。使用某种copy-elision但是在传递给函数的参数上,而不是在返回值(NRVO)上。

3 个答案:

答案 0 :(得分:2)

按值传递意味着复制。此复制可以省略,但在语义上按值传递仍在复制。您也可以通过引用传递以避免此副本。请注意,这些是允许复制省略的唯一情况:

  • 在退货声明中
  • in throw-expression
  • 带有尚未绑定参考的临时
  • 和另一个与例外有关的事项

这就是为什么:

bar(f);
bar(Foo());

只有第二个涉及复制省略。 Pre-C ++ 11,只需使用引用或使用Boost。

答案 1 :(得分:1)

使用以下语法:

void bar(const Foo& f)
{
    std::cout << "Inside bar\n";
}

上面的代码将对象作为参考传递。这样可以有效地复制对象的地址(如指针),但可以像原始对象一样处理引用。

答案 2 :(得分:0)

您可以使用类Foo的引用(或指针)作为函数bar()的参数。这样可以避免从作为参数传递给函数bar()的对象创建临时对象,因此不会调用复制构造函数。