zoukankan      html  css  js  c++  java
  • 重载=运算符为何要返回一个引用?

      一个自定义类,如果没有重载其=运算符,那么编译器将自动生成一个。但是此编译器自动生成的重载函数可能不安全。这是因为它采用了所谓的“浅拷贝”,也就是对于指针而言,它拷贝的是指针的值,而不是其指向的内存空间。那么这个内存空间就有了两个指针指向它,且类对象要析构两次,但是内存空间只能被释放一次,那么第二次就会出现访问错误。

      要避免这种“浅拷贝”问题,就需要重载=运算符。这是一个二元运算符,函数名和参数比较容易确定,重点是其返回类型。一般来说,要返回一个类的引用类型。这是因为要能实现所谓的“链式编程”。我存在过的疑问是,为什么要返回一个引用,才能实现所谓的“链式编程”呢?这里从代码出发,进行思考与总结。

    class Student
    {
    public:
        Student(const char* name);~Student();
        Student& operator=(const Student &student);private:
        char *m_name;
    };
    //测试代码
    Student s1("Lee"); Student s2("Diwen"); Student s3("Tom");

    //先执行s2 = s1, 即执行 s2.operator=(s1), 返回的是s2的引用 //然后执行s3 = s2, 即执行 s3.operator=(s2) s3 = s2 = s1;

      =的链式编程执行顺序是从右向左的。因此右边需要返回一个Student类型的对象,是肯定的。那么问题是,为何要返回一个引用呢?

      观察一下重载=运算符的函数,参数类型是一个常量引用,也即是说传进去的实参必须是一个左值。而如果返回类型是Student,那么返回的就是一个匿名对象(右值),作为链式编程,此返回值(右值)又要作为实参传进去,那么显然不行。那么,如果参数改成一个Student类型,是不是就可以传匿名对象了呢?是可以的。不过如此一来,还要调用类的拷贝构造函数以初始化形参,如果没有写拷贝构造函数,那么对于有一个指针成员变量的Student类而言,仍是危险的。事实上也没有什么必要把参数定为一个Student类型。

      如此回答一开始的问题,这是因为作为链式编程,返回值将作为实参,而=运算符重载函数的形参是引用类型,则传进去的实参必须是一个左值。那么此函数也就必须要返回引用类型才行。

    ---------------------------

    修正:以上结论有误。形参是引用,实参可以是匿名对象。那么返回引用的原因也仅仅是避免因返回是个对象而调用了拷贝构造函数。

    ---------------------------

    2018-04-27,看到以前的笔记,笑了笑,真是胡言乱语了,const引用可以绑定到右值,而重载的赋值运算符返回一个引用当然是为了避免没有意义的拷贝了。

  • 相关阅读:
    Linux产生coredump文件(core)
    shell脚本每五分钟执行一次可执行程序(nohup)
    VIM快捷操作
    日期正则表达式
    istringstream字符串流对象
    json和pickle模块
    sys模块
    random模块
    time模块
    python的模块
  • 原文地址:https://www.cnblogs.com/demon90s/p/4654180.html
Copyright © 2011-2022 走看看