一、引用的概念

引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。引用的声明方法:
 类型标识符 &引用名 = 目标变量名;

为一个变量起一个别名。假如有一个变量a,想给它起一个别名b,可以这样写:

 int a;             //定义a是整型变量
int &b=a; //声明b是a的引用

二、引用的一些规则

(1)引用被创建的同时必须被初始化,指针则可以在任何时候被初始化。
(2)不能有NULL引用,引用必须与合法的存储单元关联,指针则可以是NULL。在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
(3)一旦引用被初始化,就不能改变引用的关系,但是指定的对象其内容可以改变。指针可以被重新赋值以指向另一个不同的对象。

例1:

void main()
{
int a1;
int &ra; // error C2530: “ra”: 必须初始化引用
}

例2:

void main()
{
int a1, a2;
int &ra = a1;
int &ra = a2; // error C2374: “ra”: 重定义;多次初始化
}

企图使b又变成a2的引用(别名)是不行的。

例3:

int main()
{
int x=;
void &rx=x; // error C2182: “rx”: 非法使用“void”类型
int a[];
int &ra[]=a; // error C2234: “ra”: 引用数组是非法的
return ;
}

上例中的两处错误说明:void修饰是不能够声明引用的,引用是不能够声明数组的,即不能够声明引用数组。

在任何情况下都不能使用指向空值的引用,一个引用必须总是指向某些对象。因此如果使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时候应该把变量声明为指针,因为这样可以赋予空值给该变量。相反,如果变量肯定指向一个对象,这时候就可以把变量声明为引用。不存在指向空值的引用这个事实意味着使用引用的代码效率比指针要高。

三、常引用

常引用声明方式:
   const 类型标识符 &引用名 = 目标变量名;
用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。

例:

int main()
{
int a;
const int &ra=a;
ra=; // error C3892: “ra”: 不能给常量赋值
a=; // OK
return ;
}

在C++面向对象程序设计中,经常用常指针和常引用作函数参数。这样既能保证数据安全,使数据不能被随意修改,在调用函数时又不必建立实参的拷贝。

四、引用之间的赋值

例:

int main()
{
int a = ;
int b = ;
printf("a = %d\n",a);
printf("b = %d\n",b);
printf("a address is:%d\n",&a);
printf("b address is:%d\n",&b);
printf("give reference for a and b\n");
int &ra = a;
int &rb = b;
printf("ra = %d\n",ra);
printf("rb = %d\n",rb);
printf("ra address is:%d\n",&ra);
printf("rb address is:%d\n",&rb);
printf("let ra = rb\n");
ra = rb;
printf("a = %d\n",a);
printf("b = %d\n",b);
printf("ra = %d\n",ra);
printf("rb = %d\n",rb);
printf("a address is:%d\n",&a);
printf("b address is:%d\n",&b);
printf("ra address is:%d\n",&ra);
printf("rb address is:%d\n",&rb);
return ;
}

程序执行结果为:
a = 1
b = 2
a address is: 0031f870
b address is: 0031f864
give reference for a and b
ra = 1
rb = 2
ra address is: 0031f870
rb address is: 0031f864
let ra = rb
a = 2
b = 2
ra = 2
rb = 2
a address is: 0031f870
b address is: 0031f864
ra address is: 0031f870
rb address is: 0031f864

从上例可知,虽然引用被初始化后,便不能改变引用的关系;但是,可以用给它赋值其它引用。引用之间赋值并不改变引用和被引用变量的地址,只改变了引用对象值 。

五、指针的引用

指针的引用就是某一指针的一个别名,对引用的操作与对指针直接操作完全一样。指针引用的声明方法:
  类型标识符 *&引用名 = 目标变量名;
在某种意义上,"*"和"&"是意思相对的两个东西,把它们放在一起有什么意义呢?。在某种程度上,指针的引用类似于二级指针(指针的指针)。

int main()
{
int x = ;
int *px = &x; //x的指针
int *& rpx = px; //x的指针的引用
int y = ;
int *py = &y; //y的指针
int *& rpy = py; //y的指针的引用
cout<<"x: "<<x<<endl cout<<"px:"<<px<<endl;
cout<<"rpx: "<<rpx<<endl;
cout<<"y: "<<y<<endl;
cout<<"py:"<<py<<endl;
cout<<"rpy: "<<rpy<<endl;
cout<<"-------------------"<<endl;
*rpx = *rpy;
cout<<"x: "<<x<<endl;
cout<<"px:"<<px<<endl;
cout<<"rpx: "<<rpx<<endl;
cout<<"y: "<<y<<endl;
cout<<"py:"<<py<<endl;
cout<<"rpy: "<<rpy<<endl;
return ;
}

程序执行结果为:
x:10
px:0013FF60
rpx:0013FF60
y:20
py:0013FF3C
rpy:0013FF3C
-------------------
x:20
px:0013FF60
rpx:0013FF60
y:20
py:0013FF3C
rpy:0013FF3C

输出说明*rpx = *rpy之间的赋值并未改变指针引用的值,即地址的值,而是改变了引用对象的值 。

若将上例中*rpx = *rpy;改为:
  rpx = rpy;
程序执行结果为:
x:10
px:0013FF60
rpx:0013FF60
y:20
py:0013FF3C
rpy:0013FF3C
-------------------
x:10
px: 0013FF3C
rpx: 0013FF3C
y:20
py:0013FF3C
rpy:0013FF3C

输出说明,指针引用之间的赋值只改变指针的值,引用对象的值没有改变

指针和引用

引用类型和指针类型都可以实现通过一个变量访问另一个变量,但访问的语法形式不同:

引用采用的是直接访问形式,指针采用间接访问形式。

除了在定义时指定的被引用变量外,引用类型变量不能再引用其它变量;而指针变量定义后可以指向其它同类型的变量。因此,引用类型比指针类型要安全。

C++ 函数 引用的更多相关文章

  1. Jmeter外部函数引用

    Jmeter外部函数引用 1.Beanshell引用Jmeter变量 添加用户自定义变量,输入变量名称和变量值,添加Debug sampler,用于输出初始变量值.

  2. perl 回调必须是函数引用

    [root@wx03 lib]# cat a1.pl use AE; use AnyEvent; ##定义watch my $t = AnyEvent->timer( after => 0 ...

  3. 【足迹C++primer】48、函数引用操作符

    函数引用操作符 struct absInt { int operator()(int val) const { cout<<val<<"<->!!!&qu ...

  4. PHP中静态变量和函数引用返回

    这两天看看PHP写的框架CI,源代码中写了很多静态变量和函数引用. 官方文档地址:http://php.net/manual/zh/language.references.return.php 简单写 ...

  5. php引用(&)变量引用,函数引用,对象引用和参数引用用法

    php引用(&)变量引用,函数引用,对象引用和参数引用用法   php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容.与C语 ...

  6. 【DB2】SQL0501N FETCH 语句或 CLOSE 语句中指定的游标尚未打开,或者游标标量函数引用中的游标变量尚未打开。 SQLSTATE=24501

    在DB2中建立存储过程时使用了隐式游标,在调用的时候报错如下: SQL0501N  FETCH 语句或 CLOSE 语句中指定的游标尚未打开,或者游标标量函数引用中的游标变量尚未打开.  SQLSTA ...

  7. KClass与函数引用详解

    继续学习Kotlin反射相关的东东. KClass: 在上一次是通过类来获取它的KClass对象: 那如果是一个对象呢?与这个对象对应的类的KClass对象又是如何获取的呢?像Java也是一样有相关机 ...

  8. php中引用&的真正理解-变量引用、函数引用、对象引用

    php的引用(就是在变量或者函数.对象等前面加上&符号) //最重要就是 删除引用的变量 ,只是引用的变量访问不了,但是内容并没有销毁 在PHP 中引用的意思是:不同的名字访问同一个变量内容. ...

  9. C++ primer(八)--内联函数 引用变量 引用传递函数参数 函数重载/模板/模板具体化

    一.内联函数     常规函数和内联函数的区别在于C++编译器如何将他们组合到程序中.编译过程的最终产品是可执行程序--由一组机器语言指令组成.运行程序时,操作系统将这些指令载入到计算机内存中,因此每 ...

  10. Jmeter函数引用和函数重定向

    在jmeter中的[选项]中选择[函数助手对话框]---这些函数可以高速有效的帮助我们开展自动化编写与校验!!!!!! 如图: 重点!!!本章的侧重点不讲函数的具体使用,函数具体的使用与java类似, ...

随机推荐

  1. 关于SX1278、SX1276、SX1262的简单详解资料

    通常的物联网解决方案和设备一直都非常昂贵,或在实施中不切合实际.理想的无线连接技术应该是低成本.高可靠性的,可进行长距离传输,且拥有超长的电池续航时间.像zigbee.Bluetooth和Wi-Fi这 ...

  2. 1555: Inversion Sequence (通过逆序数复原序列 vector的骚操作!!!)

    1555: Inversion Sequence Submit Page    Summary    Time Limit: 2 Sec     Memory Limit: 256 Mb     Su ...

  3. nodeJs搭建简单服务器

    实现简单的例子:hello word 把第一个文件命名为server.js 在server.js里写入 var http  = require("http"); http.crea ...

  4. Robosup3D平台搭建

    目录 1.安装simspark及默认播放器 安装依赖库/下载simspark源码 编译并安装simspark 编译并安装rcssmonitor3d播放器 2.安装Roboviz播放器 安装java 安 ...

  5. 【10.21总结】一个渗透测试练习实例——发现未知的漏洞(Race condition)

    Write-up地址:Exploiting an unknown vulnerability 作者:Abhishek Bundela 这篇文章跟我之前看到的文章不太一样,作者是按照一个练习的方式简单描 ...

  6. 可用的ntp服务器

    操作系统中带的:time.windows.com 和 time.nist.gov  网上查到一个公共的:cn.ntp.org.cn 以上三个连接多次才成功一次,速度不好. 在移动电视盒子上有一个配置: ...

  7. Playing audio from Node.js using Edge.js

    http://tomasz.janczuk.org/2014/06/playing-audio-from-nodejs-using-edgejs.html

  8. 大数据入门第四天——基础部分之轻量级RPC框架的开发

    一.概述 .掌握RPC原理 .掌握nio操作 .掌握netty简单的api .掌握自定义RPC框架 主要内容 1.RPC是什么 RPC(Remote Procedure Call)—远程过程调用,它是 ...

  9. 【转载】D3D中的Texture应用示例

    原文:D3D中的texture应用示例 本文列举了Direct3D中各种纹理应用实现:黑暗贴图,发光贴图,漫反射映射贴图,细节纹理,纹理混合,有较详尽的注解.其中黑暗贴图,发光贴图,细节纹理都是采用多 ...

  10. 4539: [Hnoi2016]树

    4539: [Hnoi2016]树 链接 分析: 主席树+倍增. 代码: #include<cstdio> #include<algorithm> #include<cs ...