最近在搞C++的引用,闲来无事,顺便写写引用的基础知识

引言:什么是引用

引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。

引用的格式:

数据类型 &引用变量名 = 目标变量名;

第一章 引用的一些基本语法

(1)&在此不是求地址运算,而是起标识作用。
(2)类型标识符是指目标变量的类型。
(3)声明引用时,必须同时对其进行初始化。
(4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
(5)声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。故:对引用求地址,就是对目标变量求地址。
(6)不能建立数组的引用。因为数组是一个由若干个元素所组成的集合,所以无法建立一个数组的别名。

第二章 引用的应用

1、作为函数的传递参数

例:

View Code

 1 #include <iostream>2 using namespace std;3 4 void foo(int &a, int &b)5 {6     int c = 0;7     c = a + b;8     cout << c <<endl;9 }
10 int main()
11 {
12     int x = 1;
13     int y = 2;
14     foo(x, y);
15
16     system("pause");
17     return 0;
18 }

其效果与值传递是一样的,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。但需要注意的是:

①使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作。这样做的好处在于:有大块数据作为参数传递的时候,可以避免将整块数据全部压栈,可以提高程序的效率;

②要达到这种效果,使用指针传递也是一样的,但是在阅读性上,还是不如引用的,因为指针这个东东,出错的概率很高>_<!

比如,这个就很不好看

View Code

 1 #include <iostream>2 using namespace std;3 4 void foo(int *a, int *b)5 {6     int c = 0;7     c = *a + *b;8     cout << c <<endl;9 }
10 int main()
11 {
12     int x = 1;
13     int y = 2;
14     foo(&x, &y);
15
16     system("pause");
17     return 0;
18 }

2、常量引用

事先需要说明一点:引用是不能直接来常量引用的,比如:int &a = 1;就是一个错误的语句。

但是我们可以通过const来实现常量引用,上面的语句,我们可以改为:const int &a = 1;

需要注意的是:这种方式的声明,不能通过引用对引用变量进行修改,但是可以对目标变量名进行修正来达到目的:

View Code

#include <iostream>
using namespace std;void foo(int *a, int *b)
{int c = 0;c = *a + *b;cout << c <<endl;
}
int main()
{int x = 1;int y = 2;foo(&x, &y);int z = 2;const int &a =z;//a = 5;  wrong!z = 4;cout << a << '\n' <<endl;system("pause");return 0;
}

输出结果为:

3
4

3、引用作为返回值

函数声明格式:类型标识符 &函数名(形参列表及类型说明);

这种使用方法的好处在于,在内存中不产生被返回值的副本(即临时变量),例如:

View Code

使用引用作为返回值时,还需要注意以下几点:

①不能返回局部变量的引用。因为局部变量会在函数返回后被销毁,因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。

②不能返回函数内部new分配的内存的引用。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成memory leak。

③可以返回类成员的引用,但最好是const。

4、引用和多态

产生这个问题的根本来源就在于:一个基类的引用可以指向它的派生类实例。这就很容易产生一个问题:引用也会产生多态效果。

例:

View Code

 1 #include <iostream>2 using namespace std;3 4 class A {5 public:6     A();7     virtual void foo() {8         cout << "a" << endl;9     };
10 };
11
12 A::A() {
13 }
14
15 class B: public A {
16 public:
17     void foo1() {
18         cout << "b" << endl;
19     };
20 };
21
22 int main()
23 {
24     B b;
25     A &a = b;
26     a.foo(); // 访问派生类对象中从基类继承下来的成员
27     // a.foo1(); // wrong!
28     b.foo();
29     b.foo1();
30     system("pause");
31     return 0;
32 }

第三章 引用和指针

不同点:

①初始化:引用必须在创建的时候就初始化,但是指针可以在任何时候被初始化

②引用不能为空,但是指针可以为NULL

③引用的对象被初始化后就无法更改,但是指针指向的对象是可以更改的

④内存:引用与被引用对象共享内存空间,系统不会为引用变量分配内存空间,但系统会为指针分配内存空间

⑤在作为形参传递的时候,引用不拷贝副本,指针拷贝副本

⑥引用访问的对象是直接访问,而指针是间接访问

关系:

引用的实现,在内部来看,其实就是用指针来实现的,可以来看一个指针和指针的引用的例子:

View Code

 1 #include <iostream>
 2 using namespace std;
 3
 4 void foo(int *&x) {
 5     *x = 100;
 6 }
 7
 8 int main() {
 9     int *x;
10     x = (int *)malloc(sizeof(int));
11     *x=300;
12     foo(x);
13     //foo(*x);// wrong cannot convert parameter 1 from 'int ' to 'int *& '
14     //foo(&x);//cannot convert parameter 1 from 'int **' to 'int *& '
15     cout << "*x = " << *x <<endl;
16
17     system("pause");
18     return 0;
19 }

从上面的例子我们可以看到,其实指针的引用本质上就是双指针。foo(*&x);这个函数也是可以编译通过得到结果的。

转载于:https://www.cnblogs.com/hustcser/archive/2013/01/02/2841992.html

[003]Reference in C++---C++引用基础知识篇相关推荐

  1. 超详细的Java面试题总结(二)之Java基础知识篇

    系列文章: 超详细的Java面试题总结(一)之Java基本知识 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(三)之Java集合篇常见问题 超详细的Java面试题总 ...

  2. 高通平台8953 Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇)

    本系列导航: 高通平台8953  Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇) 高通平台8953 Linux DTS(Device Tree Source ...

  3. SP 短信开发-基础知识篇

    SP 短信开发-基础知识篇 很土的话题,但是最近帮朋友做这个东西,所以写点东西出来给初学者参考. 一.准备资料 SP开发资料网站上有很多,但是主要是以下几个文档: 1.MISC1.6 SP订购通知接口 ...

  4. 计算机基础知识题库选择题,计算机基础知识篇选择题库

    计算机基础知识篇选择题库 (6页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 15.9 积分 计算机基础知识篇选择题库1.微型计算机的性能指标不包括___ ...

  5. Hadoop学习笔记—15.HBase框架学习(基础知识篇)

    Hadoop学习笔记-15.HBase框架学习(基础知识篇) HBase是Apache Hadoop的数据库,能够对大型数据提供随机.实时的读写访问.HBase的目标是存储并处理大型的数据.HBase ...

  6. Android camera(4)---Android Camera开发之基础知识篇

    Android Camera开发之基础知识篇 转自:https://blog.csdn.net/feiduclear_up/article/details/51968975#jump5 概述 Andr ...

  7. 测试岗位面试前复习之【测试基础知识篇】

    测试基础知识篇 一.app测试相关 1.android与ios的app测试的区别: 2.app测试和web测试的重点: 3.性能测试考量的指标: 4.app的性能测试,需要重点关注哪些方面? 5.站在 ...

  8. python独立网站教程_python从零到独立建设网站系列教程之基础知识篇(二)

    python从零到独立建设网站系列教程之基础知识篇(二)python的安装在Windows上安装python点击Download链接 然后就是按导航走点击确认,需要注意的是要把python加入到系统变 ...

  9. 基金投资从入门到精通之一:基础知识篇

    第一篇 基础知识篇 第一节      认识基金 基金投资入门系列--基础知识 1.什么是证券投资基金? 通俗地说,证券投资基金是通过汇集众多投资者的资金,交给银行保管,由专业的基金管理公司负责投资于股 ...

最新文章

  1. BNUOJ 52305 Around the World 树形dp
  2. python 2x可以打么_15分钟让你了解Python套路,看你能不能坚持的住
  3. python转嵌入式c_在C嵌入式python中刷新导入
  4. golang map的无序性验证
  5. 关于阈值化函数cvThreshold()
  6. 中职计算机基础课教学策略研究,中职计算机基础知识教学方法及教学策略研究.doc...
  7. MakeDirZ.bat
  8. 2017秋-软件工程第八次作业-第九周例行总结
  9. 分布式存储系统学习笔记(三)—分布式键值系统(2)—淘宝Tair
  10. iOS:主流启动优化方案浅析
  11. JNPF开发平台3.3企业版框架 力软敏捷开发框架源码7.0.6旗舰版
  12. 职业生涯规划不会做?首先要知道职引生涯规划!
  13. 时间戳转化为YYYY-MM-DD-XX-MM-UU日期格式
  14. python 人脸相似度计算
  15. Spotfire 条形图属性 直线和曲线 格式设置
  16. solidworks2016安装教程
  17. 稀土配合物Ln(DBM)3(Cz-PBM)|Tb(DBM)3(Cz-PBM)|Gd(DBM)3(Cz-PBM)|Ir(L)2(DBM-Ox)Ir(L)2(DBM-Cz)qiyue
  18. GanttChart
  19. 新媒体运营教程:策划一场成功漂亮的活动策划
  20. 普通家电秒变智能,同为(TOWE)智能联动节能插排APZ-1014UMC3

热门文章

  1. Oracle创建触发器的普通应用
  2. [Web开发] 在网页中动态加入RSS feed 元素
  3. 深度学习笔记三:Softmax Regression
  4. 分数阶累加的Python实现
  5. 非监督HMP算法的物体识别
  6. python引用文件的方法_[项目实践] python文件路径引用的
  7. RocketMQ--生产者与消费者的简单示例
  8. 赋值运算符||位运算符||三元运算符
  9. Python+Selenium 自动化-指定chrome驱动运行selenium实例演示,运行指定位置下的浏览器驱动
  10. QT5生成可执行文件总结