赋值运算符重载:返回 void 与返回引用参数

Assignment operator overloading: returning void versus returning reference parameter

我在网上看到的一些赋值重载运算符的例子是这样的:

#include <iostream>
using namespace std;

class Distance {
   private:
      int feet;             // 0 to infinite
      int inches;           // 0 to 12
   public:
      // required constructors
      Distance(){
         feet = 0;
         inches = 0;
      }

      Distance(int f, int i){
         feet = f;
         inches = i;
      }

      void operator = (const Distance &D ) { 
         cout << "assigning..." << endl;
         feet = D.feet;
         inches = D.inches;
      }

      // method to display distance
      void displayDistance() {
         cout << "F: " << feet <<  " I:" <<  inches << endl;
      }

};

int main() {
   Distance D1(11, 10), D2(5, 11);

   cout << "First Distance : "; 
   D1.displayDistance();
   cout << "Second Distance :"; 
   D2.displayDistance();

   // use assignment operator
   D1 = D2;
   cout << "First Distance :"; 
   D1.displayDistance();

   return 0;
}

它们 return 从重载函数中无效。如果 D1 是被调用的对象,这对我来说很有意义。

其他示例 return 对 class 对象的引用。

#include <iostream>
using namespace std;

class Distance {
   private:
      int feet;             // 0 to infinite
      int inches;           // 0 to 12
   public:
      // required constructors
      Distance(){
         feet = 0;
         inches = 0;
      }

      Distance(int f, int i){
         feet = f;
         inches = i;
      }

      Distance& operator = (const Distance &D ) { 
         cout << "assigning..." << endl;
         feet = D.feet;
         inches = D.inches;
         return *this;
      }

      // method to display distance
      void displayDistance() {
         cout << "F: " << feet <<  " I:" <<  inches << endl;
      }

};

int main() {
   Distance D1(11, 10), D2(5, 11);

   cout << "First Distance : "; 
   D1.displayDistance();
   cout << "Second Distance :"; 
   D2.displayDistance();

   // use assignment operator
   D1 = D2;
   cout << "First Distance :"; 
   D1.displayDistance();

   return 0;
}

这对我来说没有意义(考虑第一个例子时)。如果在第一个示例中 D1 = D2; 调用类似 D1.=(D2); 的东西,为什么第二个示例在这种情况下会起作用?是不是有点像 D1 = D1.=(D2);?在一天结束时它有什么不同吗?

作为约定,赋值运算符通常是returns引用(对*this);这使得链接赋值成为可能,就像那些 built-in 类型的行为一样。例如

Distance D1, D2, D3;
D1 = D2 = D3;

对于D1 = D2;,相当于D1.operator=(D2);。第二种情况不会改变,返回值只是被丢弃。对于D1 = D2 = D3;,它等同于D1.operator=(D2.operator=(D3));。请注意,返回值(即对 D2 的引用)用作在 D1.

上调用的赋值运算符的参数

尽管 C++ 语言允许您使用任何 return 类型(包括 void)重载赋值运算符,但您应该强烈考虑遵循广泛使用的约定,即 return 从操作员。

这样做的理由是

A = B;

无论分配 returns 什么,都可以工作,而

A = B = C;

这是一个完美的赋值链将会中断,除非 B = C return 是 assignment-compatible 到 A 的东西(通常是与A).

另一个问题是在必须将对象作为较大表达式的一部分进行比较的情况下,例如

mytype obj;
while ((obj = read_obj(cin)) != END_OBJ) {
    ...
}

因此,returning void 的最大缺点是无法链接赋值并在不允许 void 的地方使用它们。