zoukankan      html  css  js  c++  java
  • c/c++赋值函数(重载=号运算符)

    c/c++赋值函数(重载=号运算符)

    首先c++里的各种运算符都是用函数实现的,比如=,就等号函数。

    所以当用=给一个对象赋值的时候,实际调用的是=号所对应的=号函数。

    分析下面的代码

    #include <iostream>
    using namespace std;
    
    class Test{
    public:
      explicit Test(){
        data = 0;
      }
      explicit Test(int d):data(d){
        cout << "C:" << this << ":"<< this->data << endl;
      }
      //拷贝构造函数                                                        
      Test(const Test &t){
        cout << "Copy:" << this << endl;
        data = t.data;
      }
      //重载=号运算符                                            
      Test& operator= (const Test &t){
        cout << "assign" << this << endl;
        if(this != &t){
          data = t.data;
        }
        return *this;
      }
      ~Test(){
        cout << "F:" << this << ":" << this->data << endl;
      }
    private:
      int data;
    };
    int main(){
      Test t1(10);
      Test t2, t3;
    
      t3 = t2 = t1;
    
      return 0;
    }
    

    重点分析下面的函数

      //重载=号运算符                                            
      Test& operator = (const Test &t){
        cout << "assign" << this << endl;
        if(this != &t){
          data = t.data;
        }
        return *this;
      }
    

    分析点:

    1,operator =是什么意思

    2,参数为什么是引用类型

    3,参数为什么有const限制

    4,为什么有if(this != &t)的判断

    5,为什么有返回值

    6,为什么返回值的类型是引用类型

    分析点解答:

    Test t2;

    t2 = t1;//实际的运作方式是t2.operator=(t1),所以函数里面的this就是t2

    1,重载类Test的=号函数,当对类Test的对象用=号操作的时候,就会调用这个重载后的函数

    2,避免调用拷贝构造函数

    3,避免不小心修改里参数t里面成员变量的值(t.data = 100;)

    4,防止自己给自己赋值

    5,为了能够使用 t3 = t2 = t1。如果没有返回值,则t3.operator=(t2=t1),的参数里面t2=t1就没有返回值,所以编译不过。

    6,不是引用也可以,用引用类型是防止老版本的编译器,在return处调用拷贝构造函数,新版本的编译器(gcc 4.8.5-20),即使不用引用类型,就不会调用拷贝构造函数。

    一个大大的疑问,求高人指点

    下面代码,重载了=号函数,故意把fun函数的返回值类型设置为引用,t2 = fun(t1);的执行结果:t2的data还是0,符合常理。

    #include <iostream>
    using namespace std;
    
    class Test{
    public:
      Test(int d = 0):data(d){
        cout << "C:" << d << " " << this << endl;
      }
      Test(Test &t){
        cout << "Copy:" << t.data << " " << this << endl;
        data = t.data;
      }
    
      Test& operator = (const Test &t){
        cout << "Assign:" << this << " = " << &t << endl;
        if(this != &t){
          data = t.data;
        }
        return *this;
        }
    
      ~Test(){
        cout << "F:" << this->data << "->" << this << endl;
      }
      int getData()const{
        return data;
      }
    private:
      int data;
    };
    
    
    Test& fun(Test &x){
      int value = x.getData();
      Test tmp(value);
      return tmp;
    
    }
    
    int main(){
      Test t1(100);
      Test t2;
      t2 = fun(t1);
      cout << t2.getData() << endl;
      //Test t2 = fun(t1);                                                
    
      return 0;
    }
    

    但是,注释掉重载的=号函数,故意把fun函数的返回值类型设置为引用,t2 = fun(t1);的执行结果:t2的data居然是100,不符合常理,求高人指点

    #include <iostream>
    using namespace std;
    
    class Test{
    public:
      Test(int d = 0):data(d){
        cout << "C:" << d << " " << this << endl;
      }
      Test(Test &t){
        cout << "Copy:" << t.data << " " << this << endl;
        data = t.data;
      }
      /*
      Test& operator = (const Test &t){
        cout << "Assign:" << this << " = " << &t << endl;
        if(this != &t){
          data = t.data;
        }
        return *this;
        }
      */
    
      ~Test(){
        cout << "F:" << this->data << "->" << this << endl;
      }
      int getData()const{
        return data;
      }
    private:
      int data;
    };
    
    
    Test& fun(Test &x){
      int value = x.getData();
      Test tmp(value);
      return tmp;
    
    }
    
    int main(){
      Test t1(100);
      Test t2;
      t2 = fun(t1);
      cout << t2.getData() << endl;
      //Test t2 = fun(t1);                                                
    
      return 0;
    }
    
  • 相关阅读:
    拷贝目录下文件,但某种类型文件例外
    编译个性化的openwrt固件
    -exec和|xargs
    OpenMP多线程linux下的使用,简单化
    clock_gettime的使用,计时比clock()精确
    openvswitch安装和使用 --修订通用教程的一些错误
    树莓派配置AP模式
    win7下的mstsc ubuntu下的rdesktop
    微信小程序-商品列表左=>右联动
    Vue.js最佳实践(五招让你成为Vue.js大师)
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/9491365.html
Copyright © 2011-2022 走看看