繁体   English   中英

当按值传递右值到函数时,为什么不调用复制构造函数

[英]Why isn't the copy-constructor called when passing rvalue by value to function

我以某种方式错过了这件事,但我感到惊讶。 考虑以下代码示例:

#include <iostream>

class A
{
    int a;

public:
    A(int a) : a(a) { std::cout << "Normal constructor called." << std::endl; }
    A(const A& orig) : a(orig.a) { std::cout << "Copy constructor called." << std::endl; }
};

void testFunction1(const A arg) { std::cout << "testFunction1()" << std::endl; }
void testFunction2(const A& arg) { std::cout << "testFunction2()" << std::endl; }

int main()
{
   testFunction1(A(2));

   testFunction2(A(2));

   return 0;
}

我期望得到以下结果:

/* Normal constructor called. */
/* Copy constructor called. */
/* testFunction1() */
/* Normal constructor called. */
/* testFunction2() */

但是我错了。 确切的结果如下:

/* Normal constructor called. */
/* testFunction1() */
/* Normal constructor called. */
/* testFunction2() */

当我按值将A(2)传递给testFunction1()时,为什么不调用复制构造函数? 这是否意味着在C ++ 98中按值或引用传递右值之间没有区别? 是优化吗? A(2)argtestFunction1()是否完全是同一对象?

是优化吗?

是! 这称为Copy Elision ,如果可能的话,可以根据编译器删除(绕过)副本。

因此,在您的情况下,编译器知道无需调用复制构造函数即可摆脱该错误,并做到了这一点。 请注意,即使您使用arg ,例如调用A的打印成员函数,出于优化目的,编译器仍然可以使用复制省略。 换句话说,不使用arg并不是此行为的原因。

如果您使用古老的编译器,或者调整当前编译器的设置,则可能会在一开始就看到期望的结果。

如Guillaume Racicot所述,使用可以确保在这种情况下进行复制省略。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM