赋值操作为什么要返回 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. layer.confirm等事件X关闭与取消监听

    关于layer.confirm的所有操作 layer.confirm('content',{ btn:['确定','取消'], cancel:function(index, layero){ cons ...

  2. LR调试脚本的时候报错Error -27796:(已解决)

    LR调试bbs脚本的时候报错: 1.Error -27796: Failed to connect to server "192.168.211.128:80": [10060] ...

  3. mySql搜索引擎

    转载自 深入浅出mysql数据库 MySQL5.5以后默认使用InnoDB存储引擎,其中InnoDB和BDB提供事务安全表,其它存储引擎都是非事务安全表. 若要修改默认引擎,可以修改配置文件中的def ...

  4. thinkphp 字段定义

    通常每个模型类是操作某个数据表,在大多数情况下,系统会自动获取当前数据表的字段信息. 系统会在模型首次实例化的时候自动获取数据表的字段信息(而且只需要一次,以后会永久缓存字段信息,除非设置不缓存或者删 ...

  5. System.Web.Mvc.ControllerBase.cs

    ylbtech-System.Web.Mvc.ControllerBase.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutral, Pub ...

  6. HDU-3068-最长回文-马拉车算法模板题

    给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input输入有多组case,不超过120组,每组输入为 ...

  7. [kuangbin带你飞]专题一 简单搜索 - E - Find The Multiple

    //Memory Time //2236K 32MS #include<iostream> using namespace std; ]; //保存每次mod n的余数 //由于198的余 ...

  8. java中一个类不想被继承怎么办?

    方法一:把类声明为final 方法二:对类中的构造器声明为private,类中提供一个static方法,完成对类的初始化.如下代码: public class Base{ private Base() ...

  9. Kindle电子书制作

    text.html: <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv=& ...

  10. 《代码整洁之道》ch1~ch4读书笔记 PB16110698 (~3.8 第一周)

    <代码整洁之道>ch1~ch4读书笔记  <clean code>正如其书名所言,是一本关于整洁代码规范的“教科书”.作者在书中通过实例阐述了整洁代码带来的种种利处以及混乱代码 ...