重载运算符+
Overloading operator +
Movie
类中有以下代码:
Movie& operator+ (const Movie& other);
现在我想过载几次,比如MOVIE1 + MOVIE2 + MOVIE3 + MOVIE4
当我尝试做:
Movie& operator+ (const Movie& left, const Movie& right);
它给了我错误:
must take zero or one argument
在搜索过程中,我看到了一些解决方案,但没有一个对我有效。
您不需要任何特殊的链式加法,只需要一个正确的运算符重载。
实现operator+
的最佳方法是为类实现operator+=
,然后根据operator+=
将operator+
编写为非成员函数。这为您提供了两个运算符,价格相当于一个运算符,降低了代码重复,并相对于隐式转换对称地处理左右参数。
实现的一个问题是返回对Movie
的引用。这将需要动态分配Movie
并记住删除它(效率低、容易出错),返回对本地的引用(未定义的行为),或者有一些更复杂的系统(不必要)。您应该只按值返回。
以下是实现的样子:
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;
}
您不必重载运算符来添加许多对象,这已经由您的operator+
处理了。您应该只更改它以返回一个值而不是引用:
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;
}
您不需要operator+()
的重载定义。
Movie MOVIE5 = MOVIE1+MOVIE2+MOVIE3+MOVIE4;
为了理解,您可以将其扩展为
Movie MOVIE5 = MOVIE1+MOVIE2+MOVIE3.opertor+(MOVIE4);
operator+MOVIE3.opertor+(MOVIE4)
返回Movie object
,然后将其与MOVIE2 object
相加,然后将结果与MOVIE1
相加,最后在MOVIE5 object
中返回结果
第一个定义:
Movie& operator+ (const Movie& other);
已经允许您将operator +
链接到一个类似于您想要编写的语句中:
MOVIE1+MOVIE2+MOVIE3+MOVIE4; // assumes all those variable are of type Movie
它之所以有效,是因为运算符返回了对Movie
(函数声明中的Movie&
)的非常数引用。此返回值将成为下一个operator +
的左操作数。
MOVIE1+MOVIE2+MOVIE3;
语句等价于(MOVIE1+MOVIE2)+MOVIE3;
。我们可以看到它是由两个表达式组成的(两者的运算符都是+
)。第一个被评估的表达式是CCD_ 23。返回值变为第二次加法的左操作数,MOVIE3
为右操作数。
EDIT:正如TartanLlama所指出的,您可能想将第一个方法的签名更改为:
Movie operator+ (const Movie& other); // return a value instead of a reference
因为您可能会返回对本地对象的引用,这将导致未定义的行为。
运算符可以正常链接:如果定义了用于添加两个Widget
并返回一个Widget
的运算符+
,则可以使用它添加任意数量的Widgets
。原因很简单:
a + b + c + d
被解析为
((a + b) + c) + d
但是,您的运算符声明有问题:您正在返回一个对Movie
的引用。对于像+
这样的操作符来说,这毫无意义,因为它创建了一个新值,而不是修改现有值。您应该在操作符中创建一个单独的Movie
对象,并按值返回。
一般来说,处理这样的操作员的最佳方式是执行操作&类中的赋值变量,并在此基础上将二进制运算符构建为非成员函数。类似这样的东西:
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;
}
还有一点:不过。把两部电影放在一起意味着什么?对于某些任意的、统一的操作,为了缩短语法而重载运算符会导致不可读,从而导致无法维护,从而导致错误的代码。
除非您正在构建DSL(可能不是),否则出于可维护性的考虑,我会坚持使用命名函数。
+
运算符是所谓的binary
运算符(与unary
相反)。这意味着它只需要两个论点:"left hand side" <operator> "right hand side"
只有非成员二进制运算符接受两个参数。
由于成员方法中的左手边始终是当前对象this
,因此所有成员二进制运算符都只接受一个参数。
这就是你找不到解决方案的原因。
相反,您可以返回一系列电影。
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- <T> 通过模板化运算符重载将 std::complex 乘以双倍
- C++20概念:需要运算符重载
- 使用赋值运算符重载从类中返回jobject
- 在运算符重载定义中使用成员函数(const错误)
- 字节到位运算符重载C++
- 为什么在运算符重载时需要参考?
- 类中 c++ 的运算符 + 重载
- 算术复合运算符重载为非成员
- 运算符重载 (+),用于添加两个具有 C++ 的数组
- 交换运算符 + 重载会导致无限递归
- 如何理解新的运算符重载?
- 向量保持复数的运算符重载
- 如何创建运算符重载?
- 链接列表运算符重载没有打印出我想要的内容
- C++:需要帮助了解运算符重载错误
- 使用模板化运算符重载 XOR 运算符失败
- 如何确保接受的C++模板类型使运算符重载?
- 运算符重载使用运算符+添加类模板