我应该使用哪种C++运算符重载变体?而且,为什么?

use*_*312 3 c++ operator-overloading

这里给出了加法运算符(+)的重载的3种变化.

我应该使用哪种变体?为什么?

class MyClass {
    int myInteger;
    double myDouble;
    public:
        MyClass(int i, double d) {
        myInteger = i;
        myDouble = d;
    }

    // Variation - 1
    //--------------
    MyClass operator +(MyClass rhsObj) {
        return MyClass(this->myInteger + rhsObj.myInteger, this->myDouble + rhsObj.myDouble);
    }

    // Variation - 2
    //--------------
    MyClass &operator +(MyClass &rhsObj) {
        rhsObj.myInteger = this->myInteger + rhsObj.myInteger;
        rhsObj.myDouble = this->myDouble + rhsObj.myDouble;

        return rhsObj;
    }

    // Variation - 3
    //--------------    
    MyClass &operator +(MyClass &rhsObj) {
        this->myInteger = this->myInteger + rhsObj.myInteger;
        this->myDouble = this->myDouble + rhsObj.myDouble;

        return *this;
    }
};


int main() {
    MyClass objOne(10, 10.5);
    MyClass objTwo(20, 20.5);

    MyClass objThree = objOne + objTwo;
}
Run Code Online (Sandbox Code Playgroud)

分配算子(=)应该是什么情况?应该使用哪种变体?

Kir*_*rov 10

取决于你需要什么.

首先,关于你的版本 - 显然

  • "Variation - 1"创建新对象,而不触及两个操作数.
  • "Variation - 2"将结果存储在第二个操作数中
  • "Variation - 3"将结果存储在"this"的第一个操作数中.

最有可能的是,Variation - 1是最受欢迎的.

为什么?因为副作用.如果您看到如下表达式:

a = b + c;
Run Code Online (Sandbox Code Playgroud)

无论是类型a,bc,你会想到什么?我认为,这a是AND 和AND 的总和,b并且未被触及,我的意思是 - 用旧的价值观. 假设,例如:cbc

a = 5;
b = 6;
c = a + b;
Run Code Online (Sandbox Code Playgroud)

你会期望,那个ab将会11在总和之后成为什么?(如果您选择变体2或3,则会发生这种情况).当然,你不能超载operator+int,但它只是一个简单而直观的例子.


一个性能改进:在您的变体1中,而不是

MyClass operator+(MyClass rhsObj)
Run Code Online (Sandbox Code Playgroud)

我会用

MyClass operator+(const MyClass& rhsObj)
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以避免使用一个额外的副本+您将使用您的代码告诉"客户",您根本不会更改rhsObj,只需使用其值.

  • @Saqib:没有!对于作业你应该使用[复制和交换习语](http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) (2认同)