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

Posted

技术标签:

【中文标题】赋值运算符重载:返回 void 与返回引用参数【英文标题】:Assignment operator overloading: returning void versus returning reference parameter [duplicate] 【发布时间】:2017-07-09 04:18:48 【问题描述】:

我在网上看到的一些赋值重载运算符示例如下:

#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;

它们从重载函数返回 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;

这对我来说没有意义(考虑到第一个示例时)。如果在第一个示例中D1 = D2; 调用类似D1.=(D2); 的内容,为什么第二个示例会在这种情况下工作?是不是类似于D1 = D1.=(D2);?到头来有什么不同吗?

【问题讨论】:

“.+”是什么意思??? 我的意思是 + 是函数名。所以调用 D1 的 + 函数。哦,我明白了。应该是 =.... D1 的 = 函数...我正在编辑。 en.cppreference.com/w/cpp/language/copy_assignment 【参考方案1】:

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

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

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

【讨论】:

您也可以将其用作子表达式,例如while (D1 = D2)(D1 = D2).foo(),尽管一些风格指南不鼓励这样做。【参考方案2】:

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

理由是这样的

A = B;

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

A = B = C;

除非B = C 返回与A (通常是与A 相同类型的对象)的赋值兼容的对象,否则完美的赋值链将会中断。

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

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

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

【讨论】:

以上是关于赋值运算符重载:返回 void 与返回引用参数的主要内容,如果未能解决你的问题,请参考以下文章

赋值运算符重载函数 引用返回 与 对象返回

运算符重载时返回值是否需要添加引用?

c++中为啥赋值运算符重载返回类型是引用

赋值函数(运算符重载)

为啥赋值运算符要返回对对象的引用?

为啥我们在赋值运算符重载中使用引用返回而不是在加减运算中?