一、引用的概念

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

为一个变量起一个别名。假如有一个变量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. 石头合并 NYOJ737 区间dp

    题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=737 石子合并(一) 时间限制:1000 ms  |  内存限制:65535 KB ...

  2. C#中 DateTime , DateTime2 ,DateTimeOffset 之间的小区别 (转载)

    闲来无事列了个表比对一下这3兄弟之间还是有一点差距的╮(╯_╰)╭   DateTime DateTime2 DateTimeOffset 日期范围 1753-01-01到 9999-12-31 00 ...

  3. mysql/mariadb将选择查询的结果重新生成一张新表格

    比如想要生成类似如下的表格 mysql> select student.*,sc.cno,course.cname,sc.grade,course.cpno,course.ccredit fro ...

  4. 针对于网络安全领域中基于PCAP流量的数据集

    网络安全领域中基于PCAP流量的数据集 MAWI Working Group Traffic Archive URL:http://mawi.wide.ad.jp/mawi/ CIC dataset ...

  5. MTCNN(Multi-task convolutional neural networks)人脸对齐

    MTCNN(Multi-task convolutional neural networks)人脸对齐 .

  6. sso(single sign on)介绍

    1. 浏览器 > 2. 系统A(www.a.com) > 3. 系统B(www.b.com) > 4. 认证中心(www.sso.com) #### ** (1)首次访问** > ...

  7. java spring 等启动项目时的异常 或 程序异常的解决思路

    今天搭建ssm项目的时候,因为pagehelper的一个jar包没有导入idea的web项目下的lib目录中,异常报错找不到pagehelper,这个问题在出异常的时候疯狂crash,让人心情十分不舒 ...

  8. 电子设备 Kindle如何删除书籍或漫画

    需要在亚马逊的官方设置好国家: 再在这里就可以管理了 要在kindle的上方小齿轮那里设置(飞行模式右边): 同步kindle 这样就能管理了

  9. 【JUC源码解析】SynchronousQueue

    简介 SynchronousQueue是一种特殊的阻塞队列,该队列没有容量. [存数据线程]到达队列后,若发现没有[取数据线程]在此等待,则[存数据线程]便入队等待,直到有[取数据线程]来取数据,并释 ...

  10. PLSQL_数据泵Datapump导入导出数据IMPDP / EXPDP(概念)(Oracle数据导入导出工具)(转)

    一.摘要 在平常备库和数据库迁移的时候,当遇到大的数据库的时候在用exp的时候往往是需要好几个小时,耗费大量时间.oracle10g以后可以用expdp来导出数据库花费的时间要远小于exp花费的时间, ...