如何重载类的operator +()
How to overload operator +() for a class
下面是一个包含operator+
方法的类。我理解它的feetInches::operator+(const feetInches &other) const
部分但在方法定义中,为什么有一个额外的feetInches
,它在这里代表什么?
class feetInches {
public:
feetInches(int inFeet = 0, int inInches = 0);
feetInches operator+(const feetInches &other) const;
void print() const;
private:
int feet;
int inches;
};
feetInches feetInches::operator+(const feetInches &other) const
{
feetInches temp;
temp.feet = feet + other.feet;
temp.inches = inches + other.inches;
return temp;
}
声明一个函数const
意味着您不能修改这个对象(当然,除非您尝试修改mutable
字段,但那是另一回事)。因此,要返回两个feetInches
的和,必须创建一个新的feetInches
对象并返回它。
// return type scope resolution parameter type
// | | |
// | | |
feetInches feetInches::operator+(const feetInches &other) const
{
// return value - you can't modify this (because method is const), so you must create
// | a third object
feetInches temp;
temp.feet = feet + other.feet;
temp.inches = inches + other.inches;
return temp;
}
编辑:作为比较,考虑重载操作符+=
:
feetInches& feetInches::operator+=(const feetInches &other)
{
feet = feet + other.feet;
inches = inches + other.inches;
return *this;
}
因为在这种情况下this
对象被改变了,操作符不再是常量。您还可以操作this
的成员,而不是临时对象。返回时,返回this的引用
应该是:
feetInches temp = *this;
temp
feetInches
是您从加法返回的对象。
操作符+必须返回一个新对象。这个临时对象就是这个新对象。
注意这是一个const函数。它的成员不能被修改。因此,使用一个临时对象来保存结果。
操作符+在c++中的语义是将两个对象加在一起并返回一个全新的结果,而不修改添加的任何一个对象。额外的temp
实例是全新的结果。
您正在实现二进制operator+
,其定义接受两个元素(未修改),并使用相加的结果生成第三个元素。代码中额外的feetInches
对象的原因是您不想修改左侧的对象。对于操作符的理解,如果考虑以下实现,可能会更简单:
feetInches operator+( feetInches const & other ) const {
return feetInches( feet+other.feet, inches+other.inches );
}
原始代码只是将单个语句拆分为4个不同的语句:对象的构造(必须是稍后使用的命名变量),设置两个字段,并返回对象。
或者,操作符重载的推荐方法略有不同:class feetInches {
int feet, inches;
public:
feetInches( int feet = 0, int inches = 0 )
: feet(feet), inches(inches) {}
// Implement += internally [*]
feetInches& operator+=( feetInches const & rhs ) {
feet += rhs.feet;
inches += rhs.inches;
return *this;
}
};
// Implement + as a free function taking the first element by value:
feetInches operator+( feetInches lhs, feetInches const & rhs ) {
lhs += rhs; // Reuse += implementation, no need to repeat
return lhs;
}
至于原因:
- 灵活性:允许
operator+
和operator+=
与单一实现 - 类型对称:允许编译器在两个操作数中执行隐式转换
-
1 + obj
,obj + 1
都将与单个实现一起工作,在成员函数方法中,1 + obj
不能被编译器解析,因为它不能在调用成员函数 之前转换第一个元素。
-
- 效率:按值获取第一个参数意味着作为第一个参数的临时变量可以被优化掉。
注意,在修改后的版本中仍然有三个对象:原始的左侧,作为operator+
的第一个参数的副本被返回,右侧,我们没有删除对象。此外,这种特殊类型的实现需要在operator+
返回语句中进行额外的复制(不能省略从参数到返回值的复制),但是对于可以移动的更复杂类型,返回语句将移动对象的内容。
这里有更多关于操作符重载的信息
[*]这是一个设计决策,operator+=
可以作为一个自由函数实现,但它可以被认为(至少我这样做),语义上+=
是第一个参数的操作。
- 运算符重载:"operator+"必须采用零个或一个参数
- "operator()"在重载运算符方法中是什么意思,在priority_queue(STL)中用作C++中的比较器?
- 重载的 operator() 在 Cython 中失败
- C++ 继承:基类中重载 operator+ 的 2 次在派生类中无法正常工作
- 当试图交换可变模板类时,如何正确地重载operator=
- 错误:使用复制和交换习惯用法的交换函数中"operator="的重载不明确
- 从 std::ostream 重载 << 运算符时,为什么编译器会给出"too many parameters for this operator function"错误?
- 放置/分段语法是否可能出现懒惰"operator or"重载?
- C++ 重载:[错误] 与'operator='不匹配(操作数类型为 'String' 和"字符串")
- 在命名空间内的类中使用带有运算符重载的字符串流时"no match for ‘operator>>’"
- 封装 ublas 并将常量引用重载到 operator()
- 无法使用"enable_if"和"is_base_of"将模板函数"operator+"的重载限制到我的类层次结构
- 如何在不重载"operator()"、"std::less"、"std
- 运算符重载错误"no match for operator error"
- 如果我没有重载,为什么我会"no match for ‘operator=’"自定义类?
- 如何重载 std::vector::operator=()
- c++ operator =重载继承,是否需要在派生类中重新定义,尽管在基类中定义
- Std::for_each, operator()重载的对象不能维持状态
- c++ operator[]重载没有响应
- c++中虚继承中的Operator =重载