• C++ 赋值函数为什么返回reference to *this?


       赋值操作为什么要返回 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 *thistest& operator= (const test &t) ,查看结果
       (c=b)=a,对象c被成功赋值,且整个过程少了两次拷贝。


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

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










  • 相关阅读:
    Operator开发实例
    Go构建HTTP服务
    Go依赖包的管理
    Go并发编程机制
    Go语言的基础数据类型
    k8s的APIServer流程介绍
    promise、resolve、reject、拦截响应
    AngularJS中service,factory,provider的区别
    scope
    sass入门
  • 原文地址:https://www.cnblogs.com/chengkeke/p/5417359.html
Copyright © 2020-2023  润新知