赋值操作为什么要返回 reference to *this? 要弄清这个问题之前,先了解函数的返回值类型:返回值类型,返回引用类型

  • 返回值类型:返回的是一个对象的副本。
  1. test operator= (const test &t)
  2. {
  3. ...
  4. cout << "赋值" << endl;
  5. return *this;
  6. }

     当程序中出现test对象之间的赋值操作时, 调用 operator函数。当return *this的时候,会执行拷贝构造test(const test&t),此时的入参为*this(即调用该operator= 函数的对象),返回的对象由*this构造而成。
  • 返回引用类型:返回的是对象本身。
  1. test &operator= (const test &t)
  2. {
  3. ...
  4. cout << "赋值" << endl;
  5. return *this;
  6. }
      和上面一样,当程序中出现test对象之间的赋值操作时,会执行operator=操作,当return *this的时候,返回的是调用该赋值操作对象的本身。

effective C++中说,是为了实现连锁赋值如a = b =c;下面下一个例子,测试一下,如果不返回引用,就不能实现连锁赋值了吗?
  1. class test
  2. {
  3. public:
  4. test() :i(10)
  5. {
  6. cout << "构造" << endl;
  7. }
  8. ~test()
  9. {
  10. }
  11. test(const test &t)
  12. {
  13. this->i = t.i;
  14. cout << "拷贝" << endl;
  15. }
  16. test operator= (const test &t)
  17. {
  18. i = t.i;
  19. cout << "赋值" << endl;
  20. return *this;
  21. }
  22. void setData(int value)
  23. {
  24. i = value;
  25. }
  26. int getData()
  27. {
  28. return i;
  29. }
  30. private:
  31. int i;
  32. };
  33. int _tmain(int argc, _TCHAR* argv[])
  34. {
  35. test a;
  36. test b;
  37. test c;
  38. cout << a.getData() << endl << b.getData() << endl<<c.getData() << endl;
  39. a.setData(20);
  40. c = b= a;
  41. cout << a.getData() << endl << b.getData() << endl << c.getData() << endl;
  42. return 0;
  43. }
结果:,可以看出仅仅是在每次赋值完后多了一次拷贝。现在考虑一个情况

如果是(c=b)=a;这种方式呢?
结果:。分析:因为c=b,返回的是一个临时的对象,因此其实最后a赋值给了一个临时变量且多了一次拷贝。
如果换成reference to *this,test& operator= (const test &t) ,查看结果
   (c=b)=a,对象c被成功赋值,且整个过程少了两次拷贝。


有的童鞋可能要问,为什么返回this,不是其他。首先明确一点,this是对象的指针。a=b,调用的是对象a的赋值构造函数,赋值结束后,肯定要返回对象a。例如int a = 1; 赋值结束后,肯定返回的是a。

总结:赋值构造函数为了实现赋值操作完成后,可以作为左值接受其他对象的赋值。因此必须返回一个reference to *this,如果返回位值类型,且如果作为左值,则其其对象得不到想要的赋值结果,因为作为左值的是值类型的临时对象。返回引用reference to *this时,赋值操作作为左值,可得到正确的赋值结果。






C++ 赋值函数为什么返回reference to *this?的更多相关文章

  1. 深入理解c++构造函数, 复制构造函数和赋值函数重载(operator=)

    注 以下代码编译及运行环境均为 Xcode 6.4, LLVM 6.1 with GNU++11 support, Mac OS X 10.10.2 调用时机 看例子 // // main.cpp / ...

  2. C++:类中的赋值函数

    先来看一个例子: #include<iostream> #include<string> using namespace std; class Student{ public: ...

  3. C++函数的返回值——返回引用类型&非引用类型

    函数的返回主要分为以下几种情况: 1.主函数main的返回值: 允许主函数main没有返回值就可结束:可将主函数main返回的值视为状态指示器,返回0表示程序运行成功,其他大部分返回值则表示失败. 2 ...

  4. 【转】C/C++ 引用作为函数的返回值

    转自:https://blog.csdn.net/weixin_40539125/article/details/81410008 这篇文章写的很好: 语法:类型 &函数名(形参列表){ 函数 ...

  5. getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析

    2013-07-18 21:35:58 getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析. char是字符型数 ...

  6. 理解C++中函数的返回

    连续几年的C++程序设计课教学中,学生中总有人要求为他们单独解释函数的返回(return)究竟是什么意思.各种书中都会详讲返回值的问题,而学生们掌握的难点却是在返回至何处执行.本文试图通过对一般函数及 ...

  7. python学习之---匿名函数,返回函数,偏函数

    1. 返回函数: 所谓的返回函数,指的是函数作为返回值.高阶函数除了可以接受函数作为参数外,同样可以接受函数作为结果返回.以下是一个可变参数的求和例子,一般求和函数是如此这般定义的: >> ...

  8. Python的函数式编程-传入函数、排序算法、函数作为返回值、匿名函数、偏函数、装饰器

    函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. ...

  9. String的构造函数、析构函数和赋值函数

    编写类String的构造函数.析构函数和赋值函数 已知类String的原型为: class String { public: String(const char *str = NULL); // 普通 ...

随机推荐

  1. Java带头节点单链表的增删合并以及是否有环

    带头节点单链表 1.优势: 1)当链表为空时,指针指向头结点,不会发生null指针异常 2)方便特殊操作(删除第一个有效节点或者插入一个节点在表头) 3)单链表加上头结点之后,无论单链表是否为空,头指 ...

  2. curl 一个使用例子

    #include <iostream> #define Main main #include <string> #include <assert.h> #inclu ...

  3. Oracle连接字符串总结

    Oracle XE 标准连接 Oracle XE(或者"Oracle Database 10g Express Edition")是一个简单免费发布的版本. 以下是语法格式: Dr ...

  4. LUOGU P4394 [BOI2008]Elect 选举 (背包)

    传送门 解题思路 一眼看上去就像个背包,然后就是\(0/1\)背包改一改,结果发现过不了样例.后来想了一下发现要按\(a\)从大到小排序,因为如果对于一个>=总和的一半但不满足的情况来说,把最小 ...

  5. Java集合综述

    Java集合图,虚线框为接口,实线框是具体的类 具体实现类 基本使用 (1)List: List基本操作 ArrayList<String> arrayList = new ArrayLi ...

  6. Spring - 整合MyBatis

    目的: 使用 Spring 容器用单例模式管理 MyBatis 的 sqlSessionFactory : 使用 Spring 管理连接池.数据源等: 将 Dao / Mapper 动态代理对象注入到 ...

  7. 初识OpenCV-Python - 005: 识别视频中的蓝色

    此次主要学习了如何将BGR转成HSV,主要用到cv2.cvtColor()和cv2.inRange()函数来识别视频中的蓝色物体. code: import cv2import numpy as np ...

  8. Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1

    Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1 C. Jumping Transformers 我会状压 DP! 用 \(dp[x][y][ ...

  9. P1417 烹调方案 /// DP(假设 简化公式 排序)

    题目大意: https://www.luogu.org/problemnew/show/P1417 题解 看第一份方法的公式 排序后01背包 #include <bits/stdc++.h> ...

  10. 如何在asp.net(C#)里用正则表达式验证手机号码