zoukankan      html  css  js  c++  java
  • c/c++ 拷贝控制 右值与const引用

    拷贝控制 右值与const引用

    背景:当一个函数的返回值是自定义类型时,调用侧用什么类型接收??

    1,如果自定义类型的拷贝构造函数的参数用const修饰了:可以用下面的方式接收。

    Test t2 = fun(t1);
    

    2,如果自定义类型的拷贝构造函数的参数没有用const修饰了:必须用下面的方式接收

    const Test& t2 = fun(t1);
    Test t2 = fun(t1);//编译不通过
    

    编译错误:

    cannot bind non-const lvalue reference of type ‘Test&’ to an rvalue of type ‘Test’
    

    解释:

    第一种条件下,用const了,由于在编译阶段,要调用Test的拷贝构造函数(其实,在运行的时候是没有调用这个拷贝构造函数的,编译器进行了优化,避免了一次没有意义的拷贝。),参数是fun(t1)的返回值,类似Test(func(t1)),但是这个参数,也就是函数的返回值是右值(临时对象),由于右值必须是const属性的,所以加上了const,就满足了右值的需要,所以可以编译通过,这时t2是可以被改变的;如果没有加const,用第一种方式(Test t2 = fun(t1);)接收,就会编译错误。

    第二种条件下,没有使用const,由于在编译阶段,要调用Test的拷贝构造函数,因为fun(t1)的返回值是右值,右值有const属性,所以编译器没有找到匹配的拷贝构造函数,就自己合成了一个拷贝构造函数。由编译器合成的这个拷贝构造函数就只能用上面写的方式接收,至于为什么,还没搞不懂!!!

    代码:

    #include <iostream>
    using namespace std;
    
    class Test{
    public:
      Test(int d = 0):data(d){
        cout << "C:" << d << " " << this << endl;
      }
      //如果参数没有const修饰,下面②处代码编译不过;
      Test( Test &t){
        cout << "Copy:" << t.data << " " << this << endl;
        data = t.data;
      }
      ~Test(){
        cout << "F:" << this->data << "->" << this << endl;
      }
      int getData()const{
        return data;
      }
      void setData(int d){
        data = d;
      }
    private:
      int data;
    };
    
    
    Test fun(Test &x){
      int value = x.getData();
      Test tmp(value);
      return tmp;
    
    }
    
    int main(){
      Test t1(100); 
      //编译器优化了,当把fun(t1)的返回值拷贝给t2时,应该调用拷贝构造函数,但是编译器优化了,就没有调用这次多余的拷贝构造函数,直接把让t2所占用的内存就是右值(fun(t1))所开辟的内存.
      const Test& t2 = fun(t1);----->①
      //Test t3 = fun(t1); ----->②
      //t2.setData(11);
      //std::cout << t2.getData() << std::endl;
    
      //Test t2(fun(t1));
    
      return 0;
    }
    
    

    github源代码

    c/c++ 学习互助QQ群:877684253

    本人微信:xiaoshitou5854

  • 相关阅读:
    两个路由器配置静态路由只能单边 ping 通
    CVE202125646:Apache Druid远程命令执行漏洞复现
    批量修改图片的格式
    十大远程控制软件排名
    Splashtop 免费60天 大赠送
    单例设计模式
    蓄水池抽样算法/水塘采样算法
    kafka安装(单机版)
    LeetCode382链表随机节点
    LeetCode398随机数索引
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/10061780.html
Copyright © 2011-2022 走看看