首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

请问关于函数返回临时副本的疑问

2013-07-09 
请教关于函数返回临时副本的疑问本帖最后由 dwjgwsm 于 2013-07-06 11:34:29 编辑《Ivor Hortonns Beginni

请教关于函数返回临时副本的疑问
本帖最后由 dwjgwsm 于 2013-07-06 11:34:29 编辑 《Ivor Hortonn's Beginning Visual C++ 2012》第295页的赋值运算符函数采用了返回引用的方式CMessage&:

 CMessage& operator=(const CMessage& aMess)
    {
      if(this != &aMess)                   // Check addresses are not equal
      {        
        // Release memory for 1st operand
        delete[] pmessage;
        pmessage = new char[strlen(aMess.pmessage) + 1];
        
        // Copy 2nd operand string to 1st
        strcpy_s(this->pmessage, strlen(aMess.pmessage)+1, aMess.pmessage);
      }
      // Return a reference to 1st operand
      return *this;
    }

其解释是,如果直接返回对象,以下语句将不能正确工作:
//motto1,motto2,motto3均为CMessage对象
(motto1 = motto2) = motto3  //motto1 = motto2返回的是原始对象的临时副本,临时副本是rvalue,                              
                            //rvalue不能调用成员函数,故(motto1.operator=(motto2)).operator=          
                            //(motto3)无法正确编译。

既然如此,我想问的是,第300页的如下函数为什么却可以正确处理三个以上对象的连加?
    CBox operator+(const CBox& aBox) const
    {
      // New object has larger length & width, and sum of heights
      return CBox(m_Length > aBox.m_Length ? m_Length : aBox.m_Length,
                  m_Width > aBox.m_Width   ?  m_Width : aBox.m_Width,


                  m_Height + aBox.m_Height);
    }

谢谢各位大大! 函数返回临时副本
[解决办法]
不同.
A + B + C 这里是把 operator+ 的返回值做为参数, 不会修改返回的值.
(A = B) = C 这里是对 operator= 的返回值赋值, 要修改那个返回值.

[解决办法]

引用:
1、既然第二次赋值是发生在一个临时对象上、而对象A只发生了一次赋值;那么,A+B+C也存在一样的问题,第二次加法发生在临时对象上、而非A上,但是测试的结果是A+B+C返回正确


    A+B+C并没有这个问题,因为我只关心它的最终返回值,并不关心它的计算的是10 + 5还是“10的副本”+5,哪怕你把10复制上10次,然后用它去加5,结果也是15,没什么区别。
 
    但(A=B)=C不同,最后那次赋值发生在对象A上还是发生在临时对象上,二者有着巨大的区别,这将决定对象A最终的状态。



引用:
2、没有解释“编译器不允许使用rvalue调用成员函数”所带来的语法矛盾


编译器不允许使用rvalue调用成员函数吗?我确实不知道这一点,如果真是这样,那我上面所说的:“可以对非简单类型的临时对象赋值”就是错误的,std::ref可能是用的const赋值操作符来实现的。

不过,下面的代码在我的编译器中编译通过:
class x
{
    public:
    x operator = ( x & a)
    {
        return * this;
    }
};

int main()
{
    
    x a, b, c;
    (a = b ) = c;
}


所以我一向都把赋值操作符的返回值声明为T const &或T const类型,从而来阻止(a = b ) = c这种表达式的编译。

热点排行