博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++引用深入探讨
阅读量:4911 次
发布时间:2019-06-11

本文共 1964 字,大约阅读时间需要 6 分钟。

(偶然翻起自己的旧博,忽然发现大三的时候写的这篇文章,仔细看看觉得写的还是那么回事,所以赶紧搭救出来)

引用的声明:   基本格式:引用类型 &引用名=被引用对象 

  1. &运算符:声明运算符& 跟取地址运算符&和位异或运算符&没有任何关系
  2. extern关键字:一般情况下 引用的声明必须指定被引用对象 唯一的例外是使用extern关键字
  3. const关键字:一般情况下 被引用对象必须是有效的左值对象 但是const关键字修饰的常引用类型允许被引用对象不是左值对象

引用的使用:引用可以被当作被引用对象的别名使用,单纯的引用是无意义的,引用主要应用于四个方面:

  1. 函数参数:可修改的实参,高效的复杂对象传递方式
  2. 函数返回值:不产生复制的返回值,返回左值类型的函数
  3. 运算符重载:为++ -- << >>等运算符提供了更贴近原意的重载方式
  4. 多态:代替指针使用,实现抽象类的引用

 引用的深入探讨:现在开始进入正题

    1.引用占内存空间吗?

        如果引用只是一个别名的话 他不应该占有内存空间 我用下面这段代码来查看

 

代码
#include 
<
iostream
>
using
 
namespace
 std;
void
 fa(){
    
int
 a[
4
];    
    cout
<<
a
<<
endl;
}
void
 fb(){
    
int
 a[
4
];
    
int
 
&
b
=
a[
0
];
    cout
<<
a
<<
endl;
    fa();
}
void
 fc(){
    
int
 a[
4
];
    cout
<<
a
<<
endl;
    fb();
}
int
 main()
{
    fc();
    getchar();
    
return
 
0
;
}

 

 

这段代码里 我用了三个嵌套的函数调用 这样 fa 和fc的栈段就把fb夹在了中间 fb的栈段大小变化的话 会导致fc中a的地址偏移 但是并不是每个分配都会导致栈段增大的 所以应该先测试一下 确定a的合适大小 使得一旦声明变量 b的栈段就增大。

int &b=a[0];注释掉的话 可以看到fc中输出的地址变了 fb没有变 那么 引用b显然占据了内存空间 我的代码在g++中编译,结果也是g++的结果。

2.引用的值不可改变吗?

一个已经初始化的引用类型对象 其引用的对象不可能被合法的改变。

前面一段代码展示给我们 引用确实占据了内存空间 ,了进一步了解其本质,我们必须获得它的地址。&取地址操作符显然是无法做到的 几乎每个学c++的人都会尝试用这种办法去取引用类型的地址,但得到的都是被引用对象的地址。

还从前面的例子入手 fb中 a的地址没有改变  fa中a的地址改变 那么 int &b的分配应该在 二者之间 于是 最可能的位置就是a中的a[4]   但输出之后我发现a[4]不是,因为数组a是跟栈逆向分配的 之后我试了这样的代码

void fb(){
    int a[4];
    int b=20;
    cout<<a[-1]<<endl;
    fa();
}

 在我的编译器中 b跟a[-1]总是相等 于是 我把int b 替换成int &b=a[0]; ok 我发现它指向了一个貌似地址的东西。改变b的指向 发现a[-1]是随之变化的 现在 我几乎可以确定 a[-1]就是b了 再用一段这样的代码来检验

void fb(){
    int a[4]={1,2,3,4};
    int &b=a[0];
    a[-1]+=4;
    cout<<b<<","<<a[0]<<endl;
    fa();
}

引用真的是不可改变的吗? 在这个例子中 我使b指向了a[1] 而不再是a[0]

3.引用和指针

从上面的例子看出 引用的内部实现和指针并无两样。如果参考其他语言的思想的话 可以得到结论:引用就是指针常量。 在c++中 引用在语法上与指针有着明显的差异 但是 他们并没有本质不同 引用是c++中实现的一种限制比较严格的常量指针 它在参与任何运算之前自动解引用。

在使用中 推荐尽量用引用代替指针,因为引用是一种比指针更安全的类型 并且有更清晰的语义(当然指针也有适合的语义)

4.其他语言

顺便一提,在C家的其他语言中 引用几乎被作为访问对象的唯一手段

C++:有指针 所有运算符会解引用 所有对象不作为引用 传递参数和返回值时如果不希望复制 则必须将形参指定为引用类型

C#: unsafe模式有指针 除了=之外的操作符会解引用 所有对象作为引用 传递参数和返回值时如果希望复制 则必须显式clone
Java:无指针 除了=之外的操作符会解引用 类似c#
javascript:无指针但是可以变通 除了=之外的操作符会解引用 没有提供复制传递的方法(郁闷)

转载于:https://www.cnblogs.com/lgh1992314/p/5834793.html

你可能感兴趣的文章
响应式布局 大中小屏幕
查看>>
iOS开发UI篇—transframe属性(形变)
查看>>
java中的单例模式
查看>>
Elasticsearch Server,2nd Edition pdf 翻译 中文
查看>>
Django-缓存
查看>>
[无关IT]就这样在凌晨写一篇吧~
查看>>
java.util.Map.Entry接口
查看>>
Linux中crond服务与crontab用法
查看>>
PLSQL连接ORACLE配置字符串简介 oracle网络配置 三个配置文件 listener.ora、sqlnet.ora、tnsnames.ora原理解释...
查看>>
分享8年开发经验,浅谈个人发展经历,明确自己发展方向
查看>>
开发使用Node.js的一个小技巧
查看>>
Mike的农场 BZOJ4177
查看>>
IT职场人生系列
查看>>
如何指定个别属性进行transition过渡
查看>>
Python爬虫基础--分布式爬取贝壳网房屋信息(Client)
查看>>
jmeter(十二)关联之正则表达式提取器
查看>>
win7系统复制文件到u盘提示文件过大怎么办
查看>>
The path "" is not valid path to the gcc binary.
查看>>
KMP算法
查看>>
NBUT [1369] A Breaking Computer
查看>>