c++为什么表达式会产生引用?

赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型.也就是说,如果i是int,表达式i=x的类型是int &

为什么i=x不是int而非要绕个弯是int &?

阅读 3.9k
1 个回答

“赋值会产生引用”的含义是,赋值表达式的返回值是引用类型。这里包含两个问题,

  • 首先,赋值表达式为什么要有返回值呢?为了支持链式的复制表达式!

    cppint a,b;
    a = b = 1;
    // 等号运算符是右结合的,相当于:
    a = (b = 1);
    

    其实是把b=1的返回值赋给了a,所以赋值表达式要有返回值。

  • 为什么不反回值,而是返回引用呢?为了效率!而且通常返回常量引用。比如你的赋值变量不是基本数据类型,而是对象时:

    cppObj a, b, c;
    a = b = c;
    

    如果b=c返回的是值,则需要在=运算结束后,调用拷贝构造函数将结果复制为返回值(因为函数结束后栈空间是要被销毁的,而局部变量存储在栈空间中)。如果返回引用,则不需要调用复制返回值,直接将引用原有的变量。

举个例子吧,比如Obj类的赋值运算符是这样重载的:

cppclass Obj{
    int x;
public:
    Obj& operator=(const Obj& rhs){
        x = rhs.x;
        return *this;
    }
};

那么在b = c结束后,返回的*thisb的引用。如果你写的是:

cppObj operator=(...){
    ...
    return *this;
}

则在return *this后,*this会被拷贝为一个新的对象作为返回值存起来。多一次拷贝构造函数的调用过程。

赋值运算符的一般重载方法,以及为何要返回*this,可以参考这篇文章:
http://harttle.github.io/2015/07/28/effective-cpp-10.html

关于拷贝构造函数、赋值运算符的调用时机以及重载方法,可以参考:
http://harttle.github.io/2015/07/23/effective-cpp-5.html

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题