Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在C++;按值传递第一个参数?_C++_Operator Overloading - Fatal编程技术网

C++ 为什么在C++;按值传递第一个参数?

C++ 为什么在C++;按值传递第一个参数?,c++,operator-overloading,C++,Operator Overloading,根据,通过值传递重载二进制运算符的第一个参数以某种方式优化表达式,如a+b+c。链接页面中的相关代码段如下所示: friend X operator+(const X& lhs, const X& rhs) { X temp(lhs); temp += rhs; return temp; } friend X operator+(X&& lhs, const X& rhs) { lhs += rhs; r

根据,通过值传递重载二进制运算符的第一个参数以某种方式优化表达式,如
a+b+c
。链接页面中的相关代码段如下所示:

friend X operator+(const X& lhs, const X& rhs) 
{    
   X temp(lhs);
   temp += rhs;
   return temp;
}
friend X operator+(X&& lhs, const X& rhs) 
{    
   lhs += rhs;
   return std::move(lhs);
}
X类
{
公众:
X&operator+=(const X&rhs)//复合赋值(不需要是成员,
{//但通常是修改私有成员)
/*将rhs添加到*此操作在此处进行*/
return*this;//通过引用返回结果
}
//在类主体中定义的朋友是内联的,并且在非ADL查找中隐藏
friend X操作符+(X lhs,//通过值传递lhs有助于优化链接的a+b+c
const X&rhs)//否则,两个参数都可能是const引用
{
lhs+=rhs;//重用复合赋值
return lhs;//按值返回结果(使用move构造函数)
}
};
关于这一点,我有两个问题:

  • 链式
    a+b+c
    表达式是如何通过此优化的
  • 假设
    X
    也覆盖了复制和移动赋值运算符和构造函数,像
    X=a+b
    这样的语句会产生任何复制吗?为什么

  • 我不知道这是否有那个例子作者的想法,但我有一些解释。考虑这个代码中发生的事情:

    X a, b, c;
    X d = a + b + c;
    
    这里,首先,
    a+b
    基本上被评估为
    operator+(operator+(a,b),c)
    。请注意,
    operator+(a,b)
    是一个右值,因此,
    lhs
    可以在
    operator+
    的外部应用程序中由move构造函数初始化

    根据
    operator+=
    实现
    operator+
    的替代方法如下:

    friend X operator+(const X& lhs, const X& rhs) 
    {    
       X temp(lhs);
       temp += rhs;
       return temp;
    }
    
    friend X operator+(X&& lhs, const X& rhs) 
    {    
       lhs += rhs;
       return std::move(lhs);
    }
    
    请注意,您需要创建一个临时对象,因为您需要一个对象来应用
    operator+=
    。使用此解决方案,
    operator+(operator+(a,b),c)
    中的
    operator+
    的两个应用程序都涉及复制构造函数

    现场演示:

    当然,您可以为右值添加第二个版本,如下所示:

    friend X operator+(const X& lhs, const X& rhs) 
    {    
       X temp(lhs);
       temp += rhs;
       return temp;
    }
    
    friend X operator+(X&& lhs, const X& rhs) 
    {    
       lhs += rhs;
       return std::move(lhs);
    }
    
    但这需要比原始值传递版本更多的输入



    通常,在需要统一左值和右值的重载的情况下,经常使用按值传递;例如,寻找统一赋值运算符。

    但是,如果我们在语句上使用值传递版本,如
    xa,b;xc=a+b
    ,调用复制构造函数是否正确?例如,在上面链接的代码中,输出
    CMM5
    表示当计算
    operator+(a,b)
    时,调用复制构造函数将
    a
    的值复制到
    operator+
    的参数中,对吗?@Diggs我相信是这样的。一定有副本。当两个操作数都是左值时,您不能仅通过移动来实现它。@Diggs您可能也感兴趣。我创建了一个单独的重载,因为它处理一个相关但不同的问题(在一种情况下,
    操作符+
    有两个重载—一个用于左值,一个用于右值)。