zoukankan      html  css  js  c++  java
  • c++赋值构造函数为什么返回引用类型?

    目录

    0. 前言

      c++默认赋值构造函数的返回值是引用类型,c++赋值运算符=的本意是返回左值的引用,我们重载赋值构造函数的时候,返回值是否应该设为引用类型呢? 按照《Effective C++》中第10条,最好是设为引用类型。

      本文,通过实验来表述返回值是否为引用类型的区别。

    1. 内置类型

      int i= 1,     j=2,    k=3;

    • case1: k = j = i

        i == 1

      j == 1

      k == 1

    • case2: (k = j) = i

        i == 1

      j == 2

      k == 1

    2. 自定义类型

      People p1("p1"),     p2("p2"),     p3("p3");

    • case1: p3 = p2 = p1
      • 使用默认赋值构造函数

          p3 == p1

        p2 == p1

      • 返回引用的People

          p3 == p1

      p2 == p1

      • 不返回引用的People

          p3 == p1

        p2 == p1

    • case2: (p3 = p2) = p1
      • 使用默认赋值构造函数

           p3 == p1

        p2 == p2

      • 返回引用的People

      p3 == p1

      p2 == p2

      • 不返回引用的People

          p3 == p2

        p2 == p2

    3. 结论

    • case1,是否返回引用没有影响;
    • case2,是否返回引用是有区别的,由于c++内置类型的赋值重载操作符是返回引用的,所以我们应该遵循规则,类的赋值构造函数返回引用类型

    4. 实验源码

    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cwchar>
    #include <functional>
    #include <iostream>
    #include <iomanip>
    #include <iterator>
    #include <string>
    #include <vector>
    #include <memory>
    
    #include <sstream>
    #include <utility>
    
    using std::cout;
    using std::endl;
    using std::string;
    using std::vector;
    using std::stringstream;
    
    void test_int()
    {
      cout << "test_int()" << endl;
      int i = 1, j = 2, k = 3;
    
      k = j = i;
    
      cout << "	i=" << i << endl; // 1
      cout << "	j=" << j << endl; // 1
      cout << "	k=" << k << endl; // 1
    }
    
    void test_int2()
    {
      cout << "test_int2()" << endl;
      int i = 1, j = 2, k = 3;
    
      (k = j) = i;
    
      cout << "	i=" << i << endl; // 1
      cout << "	j=" << j << endl; // 2
      cout << "	k=" << k << endl; // 1
    }
    
    class People
    {
     public:
      People(const string &_name = "")
          : name(_name)
      {}
    
      People operator=(const People &_p)
      {
        name = _p.name;
        return *this;
      }
    
      string name;
    };
    
    void test()
    {
      cout << "test(): not reference" << endl;
      cout << "	p3=p2=p1" << endl;
      People p1("p1"), p2("p2"), p3("p3");
    
      p3 = p2 = p1;
      
      cout << "		p2.name=" << p2.name << endl; // p1
      cout << "		p3.name=" << p3.name << endl; // p1
    }
    
    void test2()
    {
      cout << "test2(): not reference" << endl;
      cout << "	(p3=p2)=p1" << endl;
      People p1("p1"), p2("p2"), p3("p3");
    
      (p3 = p2) = p1;
      
      cout << "		p2.name=" << p2.name << endl; // p2
      cout << "		p3.name=" << p3.name << endl; // p2
    }
    
    class PeopleRef
    {
     public:
      PeopleRef(const string &_name = "")
          : name(_name)
      {}
    
      PeopleRef& operator=(const PeopleRef &_p)
      {
        name = _p.name;
        return *this;
      }
    
      string name;
    };
    
    void test_ref()
    {
      cout << endl;
      cout << "test_ref(): reference" << endl;
      cout << "	p3=p2=p1" << endl;
      PeopleRef p1("p1"), p2("p2"), p3("p3");;
    
      p3 = p2 = p1;
    
      cout << "		p2.name=" << p2.name << endl; // p1
      cout << "		p3.name=" << p3.name << endl; // p1
    }
    
    void test_ref2()
    {
      cout << "test_ref2(): reference" << endl;
      cout << "	(p3=p2)=p1" << endl;
      PeopleRef p1("p1"), p2("p2"), p3("p3");;
    
      (p3 = p2) = p1;
    
      cout << "		p2.name=" << p2.name << endl; // p2
      cout << "		p3.name=" << p3.name << endl; // p1
    }
    
    class PeopleDefault
    {
     public:
      PeopleDefault(const string &_name = "")
          : name(_name)
      {}
    
      string name;
    };
    
    void test_default()
    {
      cout << endl;
      cout << "test_default()" << endl;
      cout << "	p3=p2=p1" << endl;
      PeopleDefault p1("p1"), p2("p2"), p3("p3");
    
      p3 = p2 = p1;
      
      cout << "		p2.name=" << p2.name << endl; // p1
      cout << "		p3.name=" << p3.name << endl; // p1
    }
    
    void test_default2()
    {
      cout << "test_default2()" << endl;
      cout << "	(p3=p2)=p1" << endl;
      PeopleDefault p1("p1"), p2("p2"), p3("p3");
    
      (p3 = p2) = p1;
      
      cout << "		p2.name=" << p2.name << endl; // p2
      cout << "		p3.name=" << p3.name << endl; // p1
    }
    
    int main ()
    {
      test_int();
      test_int2();
      
      test();
      test2();
      
      test_ref();
      test_ref2();
    
      test_default();
      test_default2();
    }

     此文章为 '永无止境'(入驻一点号的媒体名称)原创,特此声明!

  • 相关阅读:
    线程池原理分析(一)-线程池体系结构
    LinkedBlockingQueue原理分析
    ArrayBlockingQueue原理分析(二)-迭代器
    ArrayBlockingQueue原理分析(一)
    ConcurrentHashMap原理分析(二)-扩容
    ConcurrentHashMap原理分析(一)-综述
    CyclicBarrier原理分析
    Jmeter集合点技术
    Jmeter关联技术
    JMeter参数化
  • 原文地址:https://www.cnblogs.com/lovers/p/3700362.html
Copyright © 2011-2022 走看看