Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.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++_Operator Overloading - Fatal编程技术网

C++ 重载运算符+;

C++ 重载运算符+;,c++,operator-overloading,C++,Operator Overloading,我在Movie类中有以下代码: Movie& operator+ (const Movie& other); 现在我想重复几次,比如说MOVIE1+MOVIE2+MOVIE3+MOVIE4 当我尝试这样做时: Movie& operator+ (const Movie& left, const Movie& right); 这给了我一个错误: must take zero or one argument 在搜索时,我看到了一些解决方案,但没有一个对我

我在
Movie
类中有以下代码:

Movie& operator+ (const Movie& other);
现在我想重复几次,比如说
MOVIE1+MOVIE2+MOVIE3+MOVIE4

当我尝试这样做时:

Movie& operator+ (const Movie& left, const Movie& right);
这给了我一个错误:

must take zero or one argument

在搜索时,我看到了一些解决方案,但没有一个对我有效。

您不需要重载定义
操作符+()

要理解这一点,您可以将其扩展为

Movie MOVIE5 = MOVIE1+MOVIE2+MOVIE3.opertor+(MOVIE4);
operator+MOVIE3.operator+(MOVIE4)
返回
Movie对象
,然后添加
MOVIE2对象
,其结果将依次添加到
MOVIE1
中,最后在
MOVIE5对象
中返回结果第一个定义:

Movie& operator+ (const Movie& other);
已允许您将
运算符+
链接到一条语句中,如您要编写的语句:

MOVIE1+MOVIE2+MOVIE3+MOVIE4; // assumes all those variable are of type Movie
它工作的原因是运算符返回了对
Movie
(函数声明中的
Movie&
)的非常量引用。此返回值成为下一个
运算符+
的左操作数

MOVIE1+MOVIE2+MOVIE3
语句相当于
(电影1+2)+电影3。我们可以看到它由两个表达式组成(对于这两个表达式,其运算符都是
+
)。计算的第一个表达式是
MOVIE1+MOVIE2
。返回值成为第二次加法的左操作数,而
MOVIE3
作为右操作数

编辑:正如TartanLlama所指出的,您可能希望将第一个方法的签名更改为:

Movie operator+ (const Movie& other); // return a value instead of a reference

因为您可能会返回对本地对象的引用,这将导致未定义的行为。

+
运算符是所谓的
二进制
运算符(与
一元
相反)。这意味着它正好需要两个参数:
“左侧”“右侧”

只有非成员二进制运算符接受两个参数

由于成员方法中的左侧始终是当前对象
this
,因此所有成员二进制运算符只接受一个参数

这就是你找不到解决办法的原因


您可以做的是返回一个电影数组。

您不必重载操作符来添加许多对象,这已经由
操作符处理了+
。您应仅将其更改为返回值而不是引用:

struct A {
    int value;
    A() : value(1) {}
    A operator+(const A& other){
        A result;
        result.value = this->value + other.value;
        return result;
    }
}; 

int main() {
    A a,b,c;
    A d = a + b + c;
    std::cout << d.value << std::endl;
    return 0;
}
结构A{ int值; A():值(1){} A运算符+(常量A和其他){ 结果,; result.value=this->value+other.value; 返回结果; } }; int main(){ A、b、c; A d=A+b+c;
std::cout您不需要任何特殊的链添加,您只需要一个正确的操作符重载

实现
operator+
的最佳方法是为类实现
operator+=
,然后将
operator+
作为
operator+=
的非成员函数编写。这样可以以一个运算符的价格获得两个运算符,减少代码重复,并对称地处理左参数和右参数icit转换

实现中的一个问题是返回对
电影的引用
。这需要动态分配
电影
,并记住将其删除(效率低下,容易出错),返回对本地电影的引用(未定义的行为),或者在适当的位置设置一些更复杂的系统(不必要).您应该按值返回

以下是实现的外观:

class Movie {
public:
    Movie& operator+= (const Movie& rhs) { 
        m_data += rhs.m_data;
        return *this;
    }

private:
    int m_data; //assume some data
};

Movie operator+ (Movie lhs, const Movie& rhs) {
    lhs += rhs;
    return lhs;
}

操作员可以正常链接:如果您定义了操作员
+
,用于添加两个
小部件
并返回一个
小部件
,则您可以使用它添加任意数量的
小部件
。原因很简单:

a + b + c + d
被解析为

((a + b) + c) + d
但是,您的运算符声明有问题:您正在返回对
电影
的引用。对于像
+
这样的运算符来说,这没有任何意义,它创建一个新值而不是修改现有值。您应该在运算符内创建一个单独的
电影
对象,并按值返回它

通常,处理此类运算符的最佳方法是在类中实现操作和赋值变量,并在此基础上将二进制运算符构建为非成员函数。类似如下:

class Movie
{
  // ...
  Movie& operator+= (const Movie &rhs)
  {
    //somehow add rhs to this
    return *this;
  }
  // ...
};

inline Movie operator+ (const Movie &lhs, const Movie &rhs)
{
  Movie result = lhs;
  result += rhs;
  return result;
}
还有一点:不过。首先,将两部电影加在一起意味着什么?对于某些任意的unituitive操作,为了缩短语法而重载运算符会导致代码无法读取,因此无法维护,因此错误


除非你正在建造一个(你可能没有),为了可维护性,我会坚持使用命名函数。

第二个版本是在
电影
中声明的吗?它应该是一个非成员函数。从
操作符+
返回引用似乎很奇怪。你确定不想按值返回吗?我不确定有什么区别。.引用会解决问题不是吗?实际上你不需要重载的
operator+()
…第一个定义处理你正在谈论的条件…想想为什么
Movie&
被返回…一个简单的
operator+(const-Movie&other)
您只需编写
电影1+movie2+movie2…
操作员将返回什么引用?@TartanLlama感谢您捕捉到这一点,让我们假设
操作员+
背后没有聪明的缓存机制(但是,总结电影意味着什么;)非成员二进制运算符有两个参数。返回电影数组会有什么帮助?我猜OP试图实现的是有一个电影列表。这就是一个数组(或std::list或QList或您正在使用的任何库).我猜这一个是编译的..但是它返回正确的答案吗?@aviam71.你为什么认为它不应该呢?@aviam71只要想想所有的豆荚类型,它们不会
class Movie
{
  // ...
  Movie& operator+= (const Movie &rhs)
  {
    //somehow add rhs to this
    return *this;
  }
  // ...
};

inline Movie operator+ (const Movie &lhs, const Movie &rhs)
{
  Movie result = lhs;
  result += rhs;
  return result;
}