《C++ Primer》学习笔记——C++引用

1. 引用是object的别名,它自己本身不是object,而指针变量则是一个object。
2. 引用必须初始化,因为它一旦绑定一个object以后,就不可再与其他object重新绑定了,如下面这个程序:
// ref.cpp
int main(void)
{
    int ival1 = 4;
    int ival2 = 5;
    int &rval1 = ival1;
    int &rval2 = ival2;
    rval1 = rval2;
    return 0;
}
编译程序:
$ g++ -g ref.cpp
使用gdb调试运行出来的程序,设置断点在return前:
(gdb) p &ival1
$1 = (int *) 0x7fffffffe1d8
(gdb) p &ival2
$2 = (int *) 0x7fffffffe1dc
(gdb) p rval1
$3 = (int &) @0x7fffffffe1d8: 5
(gdb) p rval2
$4 = (int &) @0x7fffffffe1dc: 5
(gdb) p ival1
$1 = 5
可以看到执行 rval1 = rval2 以后,引用 rval1 并不像指针一样,改为指向变量 ival2,自始至终都是和 ival1 的地址相同(都是0x7fffffffe1d8,指针变量则会有自己独立的地址),而且这带来的另外一个效果是 ival1 被赋值5。这就是引用“object别名”的意义所在,修改引用,就是修改被其引用的变量。
3. 除了两种特殊情况以外,引用必须和被引用的对象类型完全一致,下面的程序编译时会报错:
int main(void)
{
    int ival = 4;
    double &rval = ival;    // 错误:类型不匹配
    return 0;
}
4. 两种特殊情况的第一种涉及到const:
我们可以对具有const属性的引用,使用任意一个,能够转成被其引用变量类型的表达式,来初始化这个引用(we can initialize a  reference to const from any expression that can be converted to the type of the reference)
对于第3点的例子,原本因为类型不匹配造成的编译错误,只要在double前加上const,
int main(void)
{
    int ival = 4;
    const double &rval = ival;
    return 0;
}
就不会有编译错误出现。
为什么会这样,调试这段程序,同样在return前加断点:
(gdb) p ival
$3 = 4
(gdb) p &ival
$1 = (int *) 0x7fffffffe1dc
(gdb) p rval
$4 = (const double &) @0x7fffffffe1c8: 4
可以看到虽然 ival 和 rval 的值都是4,但是地址却不一样!这与最初的引用就是object的别名似乎有冲突!其实不是这样,《C++ Primer》给出解释(原文是double转int):编译器为了保证引用的对象和引用本身是同一种类型,会将中间那行代码转换为如下的效果:
const double temp  = ival;
const double &rval = temp;
所以rval实际上引用的是一个无名的临时变量(temporary object),这个object有自己的地址空间,但是没法通过变量名来索引。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值