引用的小理解

在很多的教科书上都写了引用是一个对象的别名,那么别名是什么意思又是怎么实现的呢?在看了一位大侠写的深入分析C++引用后,豁然开朗,在这里分享给大家:

其实确实是有别名这种东西的。c++标准规定,引用可以占内存也可以不占,取决于编译器实现。占内存的实现就是使用指针了。很多编译器为了简单都全部采用这种实现方法。不占内存的实现呢,是引用和引用的对象在同一个函数中的时候。局部变量名其实是一个相对于栈基址的偏移量,这种情况下你定义这个局部变量的引用,编译器可以直接给这个引用赋同样的偏移值,这样引用名和变量名完全没有区别。这就是别名的含义了。不过引用作为函数参数的时候确实只有用指针实现这种方法了。

在大多数编译器中,引用其实就是 c++ 中的常量指针,它也拥有内存空间,最关键的是引用是一种会被编译器自动解引用的指针,引用之所以要初始化是因为 const 类型变量必须初始化,这个指针也必须有所指。

void main()
{
    /
    //引用说白了就是一个常量指针 const int* 
    /引用的示例//
    int i=10;
    int& j=i;
    j++;
    cout<<i<<","<<j<<endl;
    cout<<&i<<","<<&j<<endl;
    /
    int i1=10;
    int* const j1=&i1;
    (*j1)++;
    cout<<i1<<","<<*j1<<endl;
    cout<<&i1<<","<<&(*j1)<<endl;
    /此处的&(*j1)=&j;
 /
}

那么在我们在类的传递函数中,经常将类类型的参数声明为引用类型,如下:

class Test
{
public: 
    Test(int x=0,int y=0);//构造函数
    Test(Test& T);//拷贝构造函数
    Test operator=(Test T);//赋值函数

/****************************************************** / 

  //Test& operator=(Test& T);//赋值函数

/******************************************************/
    virtual ~Test();
public:
    int x;
    int y;
    friend Test operator+(const Test& A,const Test& B);
};
Test::Test(int x,int y)//构造函数
{
    this->x=x;
    this->y=y;
    cout<<"X"<<endl;
}
Test::Test(Test& T)//拷贝构造函数
{
    cout<<"Test"<<endl;
}
Test Test:: operator=(Test T)
{
  cout<<"="<<endl;
  return T;
}

/****************************************/

/*

Test& Test:: operator=(Test& T)
{
  cout<<"="<<endl;
  return T;
}

*/

/****************************************/

Test::~Test()
{
    cout<<"this ~Test"<<endl;
}
void main()
{
    Test a,b;
    a=b;

}

当运行这段代码的时候,会发现拷贝构造函数被调用两次。

当你使用"="的引用版本的时候你会发现,拷贝构造函数没有被调用过。

此时就发现为甚两种版本,拷贝构造函数被调用的次数不同呢,其实本质上是引用在作怪。

引用从官方的说法上来看,就是给一个对象起了一个别名。其实我感觉从本质上来说,引用使这个对象突破了作用域的限制,让这个对象能够传入到另一个作用域中,被使用。

以上面的代码为例:

Test& Test:: operator=(Test& T)
{
  cout<<"="<<endl;
  return T;
}

当调用发生的时候即:A=B; 就等价于 A.operator=(B);因为引用的使用,进入函数中就省去了拷贝构造这一部分,此时B这个对象的作用域就扩展到

{
  cout<<"="<<endl;
  return T;
}

中。

这样做的好处是,减少了对象在函数传递过程中的拷贝(因为对象中的数据量可能很多很大),减少了开销。当然在函数中进行的一些修改也会反应到被传递进来的B上,因此当在函数中不希望对B进行修改的时候,尽量加上const 修饰





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值