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

Joe*_*ass 3 c++ operator-overloading assignment-operator

我在网上看到的一些赋值重载操作符示例如下所示:

#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;
}
Run Code Online (Sandbox Code Playgroud)

它们从重载函数返回void.如果D1是被调用的对象,这对我来说很有意义.

其他示例返回对类对象的引用.

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

das*_*ght 8

虽然C++语言允许您使用任何返回类型重载赋值运算符(包括)void,但您应该强烈考虑遵循从运算符返回对受理人的引用的广泛惯例.

它的基本原理是

A = B;
Run Code Online (Sandbox Code Playgroud)

无论作业返回什么,都会有效

A = B = C;
Run Code Online (Sandbox Code Playgroud)

除非B = C返回与赋值兼容的东西A(通常是与其相同类型的对象A),否则这是一个完美的赋值链.

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

mytype obj;
while ((obj = read_obj(cin)) != END_OBJ) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

因此,返回的最大缺点void是无法链接分配并在void不允许的地方使用它们.


son*_*yao 5

按照惯例,赋值运算符通常返回(*this)的引用;就像那些内置类型的行为一样,这使得链接分配成为可能。例如

Distance D1, D2, D3;
D1 = D2 = D3;
Run Code Online (Sandbox Code Playgroud)

因为D1 = D2;,它等效于D1.operator=(D2);。对于第二种情况,它不会更改,只是丢弃返回的值。因为D1 = D2 = D3;,它等效于D1.operator=(D2.operator=(D3));。请注意,返回值(即对的引用D2)用作on上的赋值运算符的参数D1