【问题标题】:How to overload compound-assignment in c++?如何在 C++ 中重载复合赋值?
【发布时间】:2015-11-08 11:42:02
【问题描述】:

point.h

...
Point operator +=(double & left, const Point & right) {
    return Point(left + right.x, left + right.y, left + right.z);
}
// std::ostream is overloaded
...

main.cpp

#include <iostream>
#include "point.h"

int main() {
    double a = 1.0;
    Point b(1.0, 1.0, 1.0);
    a += b;
    std::cout << a << std::endl;
}

输出:

1

我想返回总和:

(2, 2, 2)

但是复合赋值时编译器会保留双精度类型。

【问题讨论】:

  • a 是双精度数。 cout &lt;&lt; a &lt;&lt; endl; 不可能返回 (2, 2, 2)。此外,+= 应该修改 LHS 操作数,而不是创建具有不同类型的新对象。
  • 您真正想做的是在 += 运算符中交换操作数,修改其中的现有点而不是创建新点,并在 main.cpp 中使用 b += a。跨度>
  • @Danilo 显示类定义。
  • 你搞混了。变量不能在 C++ 中改变它们的类型;一旦a 是双倍,它总是双倍。也许你的意思是Point c = a + b;

标签: c++ class type-conversion operator-overloading compound-assignment


【解决方案1】:

此运算符定义

Point operator +=(double & left, const Point & right) {
    return Point(left + right.x, left + right.y, left + right.z);
}

是错误的,因为它不给左操作数赋值,也不返回被赋值对象的左值。

一般来说,最好将这些运算符定义为类成员函数。

我会这样定义它

class Point
{
    //...
    Point & operator +=( const Point &rhs )
    {
        x += rhs.x;
        y += rhs.y;
        z += rhs.z;

        return *this;
    }
    //...
};

至于你的代码,尤其是这个语句

a += b;

那么不清楚是否存在将 double 类型的对象(对象 a 具有的类型)转换为 Point 类型的转换构造函数,因为您没有显示类定义。正如我已经指出的那样,您定义的运算符不会更改左操作数(Point 类型的临时对象,将基于对象a 创建)。因此,即使上面的记录在任何情况下都是正确的,原始对象a 也不会被更改。

对于用作左操作数的 double 类型的对象,您可以定义运算符 + 而不是运算符 +=。

例如

const Point operator +( double lhs, const Point &rhs )
{
    Point p( rhs.x + lhs, rhs.y + lhs, rhs.z + lhs );

    return p;
}

您的类的实现细节可能会有所不同,因为我没有看到类定义。然而,这个定义证明了这个想法。

在这种情况下你可以写

double a = 1.0;
Point b( 1.0, 1.0, 1.0 );

std::cout << a + b << std::endl;

得到预期的结果

(2, 2, 2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 2011-02-21
    • 2021-04-24
    • 2020-04-17
    相关资源
    最近更新 更多