引用在成员函数中的几种情况

先看下面一段代码:
class CRet
{
};

class CTest
{
public:
 CRet Get1()
 {
  return m_objCRet;
 }

 CRet& Get2()
 {
  return m_objCRet;
 }

private:
 CRet m_objCRet;
};

int main(int argc, char* argv[])
{
 CTest objCTest;    // a:调用构造函数

 objCTest.Get1();    // b:调用拷贝构造函数、析构函数
 objCTest.Get2();    // c:不调用

 CRet objCRet1 = objCTest.Get1(); // d:调用拷贝构造函数; objCRet1拷贝了一份m_objCRet
 CRet& objCRet2 = objCTest.Get1(); // e:调用调用拷贝构造函数; objCRet2拷贝了一份m_objCRet
  
 CRet objCRet3 = objCTest.Get2(); // f:调用拷贝构造函数; objCRet3拷贝了一份m_objCRet
 CRet& objCRet4 = objCTest.Get2(); // g:不调用; objCRet4引用了一份m_objCRet

 return 0;      // h:调用4次析构函数
}
上述代码中对比了返回值是否引用、接受值是否引用。下面对每个语句进行解释。
a: 这个无需多讲。

b: Get1返回时,系统会产生一个CRet临时对象,当然这个临时对象我们看不到。但它的确存在,而且还会调用拷贝构造函数。然而,这个临时对象却没变量来接收,系统当然不会允许这个临时对象继续存在,于是就立即把它析构掉。

c: Get2返回的是引用,没有临时对象的产生。所以这里没有调用拷贝构造函数和析构函数。

d: Get1很荣幸,因为它返回的值由objCRet1通过调用拷贝构造函数来接收。

e: Get1返回时,系统产生了CRet临时对象,所以会调用拷贝构造函数。然而系统不能将该临时对象析构,因为objCRet2引用了它。

f: 这个情况与d的相似,由objCRet3通过调用拷贝构造函数来接收返回值。

g: Get2返回的是引用,该返回值还继续被objCRet4引用,所以不会调用(拷贝)构造函数。但此时objCRet4与m_objCRet是同一份。注意了,修改objCRet4就会导致m_objCRet的改变。

h: 这里也无需多讲。

延伸阅读:临时对象
临时对象不是平时在函数体内看到的临时变量。它不出现在源代码中,建立一个没有命名的非堆(non-head)对象时会产生临时对象。这种未命名的对象通常会在两种条件下产生:为了使函数调用而进行隐式类型转换以及函数返回对象时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值