zoukankan      html  css  js  c++  java
  • C++ 赋值构造函数的返回值到底有什么用?且返回值是否为引用类型有什么区别吗?

    首先定义类Person

    class Person{
    public:
      string name;
      Person()=default; //默认构造函数
       Person(string nam):name(nam){} 
       void operator=(const Person& p){ //赋值构造函数
              this->name=p.name;
        }
    };
    Person a("xiaoming");
    Person b;
    cout<<b.name<<endl; //
    b=a;//执行赋值构造函数
    cout<<b.name<<endl; //xiaoming

    由上,赋值操作已完成,可为什么赋值构造函数还有个返回值

    为什么有返回值?(初学者可能不理解b=a为什么会产生返回值)

    首先b并不接收返回值(b=a让某些初学者误认为b接受返回值)

    其实只要把b=a 看成是 a.operator=(b)就可以了

    b=a的返回值就相当于a.operator=(b)这个函数的返回值

    比如

    我们来修改赋值构造函数返回值为一个具体的整数100

    int operator=(const Person& p) {
        this->name = p.name;
        return 100;
    }
    
    cout<<10+(b=a)<<endl; // 110

    结果,(b=a)产生了一个临时变量100,然后这个临时变量和10相加得结果110,这个临时变量就是我们所谓的返回值

    那返回值到底有什么用呢?

    可以让对象进行链式操作

    比如我们将返回值更改为这个对象的引用

    Person& operator=(const Person& p) {
        this->name = p.name;
        return *this;
    }
    
    Person& showName() {
        cout<<this->name;
        return *this;
    }
    
    (b=a).showName(); //xiaoming

    我们在给b赋值以后还能再让其还能再执行函数showName

    那返回值是引用类型和非引用类型有区别吗?

    区别当然大了

    1.对一个对象进行两次连续的赋值操作

    首先新建一个对象c

    Person c("huanghuang");

    1)赋值构造函数返回值是引用类型

    (b=a)=c;
    cout<<b.name<<endl; //huanghuang
    
    

    2)赋值构造函数返回值不是引用类型

    
    
    (b=a)=c;
    cout<<b.name<<endl; //xiaoming

    可以看到结果不同,究其原因,第2)种情况让系统拷贝了一份临时变量,因而是c给临时变量赋值,而非对象b

        表一    结果对比表                                                 

        返回值类型           (b=a)执行后产生的结果            

          Person&                       b的引用                           

           Person             b的一份拷贝(临时变量)         

    扩展阅读:

    临时变量又叫做右值,左值就是非临时变量

    详细解释:( https://blog.csdn.net/thisinnocence/article/details/23883483  https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/  https://blog.csdn.net/zhangsj1007/article/details/79940370【三篇关于左值右值的讲解】)

    粗糙解释:就是在执行某段代码中间产生的临时变量,这个临时变量在执行完这段代码后就会被析构,除非你引用了这个临时变量。

    //如果返回值类型不为引用  产生了临时变量  我们引用这个临时变量

    Person&& d=b=a;

    Person&用于引用一个已经被定义好的Person对象

    Person&&则是用于引用一个临时的Person对象(认领这块无主之地)

    2.将一个对象连续赋值给两个对象

    即a=b=c

    首先我们增加一个拷贝构造函数 再给赋值构造函数增加一个输出

    Person(const Person&p) { cout<<"copy constructor"<<endl; }
    Person& operator=(const Person& p) {
        cout << "copy assignment constructor" << endl;
        this->name = p.name;
        return *this;
    }

    a=b=c;

    1)赋值构造函数返回值为引用类型
    copy assignment constructor
    copy assignment constructor

    2)赋值构造函数返回值为非引用类型
    copy assignment constructor
    copy constructor
    copy assignment constructor
    copy constructor

    我们看到赋值构造函数返回值为非引用类型时,导致系统为其拷贝生成两个临时变量

    虽然最后达到的目的一致,但是增加了内存开支

    综上,复制构造函数的返回值为引用类型比较好,在给多个对象赋值时,可以节省内存开支,在进行链式操作时,不但可以节省内存开支,还可以对其进行修改性操作

     

  • 相关阅读:
    LeetCode 382. Linked List Random Node
    LeetCode 398. Random Pick Index
    LeetCode 1002. Find Common Characters
    LeetCode 498. Diagonal Traverse
    LeetCode 825. Friends Of Appropriate Ages
    LeetCode 824. Goat Latin
    LeetCode 896. Monotonic Array
    LeetCode 987. Vertical Order Traversal of a Binary Tree
    LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays
    LeetCode 636. Exclusive Time of Functions
  • 原文地址:https://www.cnblogs.com/kiik/p/10708356.html
Copyright © 2011-2022 走看看