C++引用

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

以下文字转载自 VBnBasic 讨论区】

【原文由阿蓉所发表】

c++比起c来除了多了类类型外还多出一种类型:引用。这个东西变量不象变量,指针不象指针,我以前对它不太懂,看程序时碰到引用都稀里糊涂蒙过去。最近把引用好好地揣摩了一番,小有收获,特公之于社区,让初学者们共享。

引用指的是对一个对象的引用。那么什么是对象?在c++中狭义的对象指的是用类,结构,联合等复杂数据类型来声明的变量,如 MyClass myclass,CDialo g mydlg,等等。广义的对象还包括用int,char,float等简单类型声明的变量,如int a,char b等等。我在下文提到“对象”一词全指的是广义的对象。c++ 的初学者们把这个广义对象的概念建立起来,对看参考书是很有帮助的,因为大多数书上只顾用“对象”这个词,对于这个词还有广义和狭义两种概念却只字不提。

一。引用的基本特性

首先让我们声明一个引用并使用它来初步认识引用。

例一:

1。 int v,k,h;

2。 int &rv=v;

3。 rv=3; //此时v的值也同时变成了3。

4。 v=5;

5。 k=rv+2; //此时k=5+2=7。

6。 h=12;

7。 rv=h;

8。 rv=20;

第1句声明了三个对象(简单变量)。

第2句的意思是:声明了一个引用,名字叫rv,它具有int类型,或者说它是对int类型的引用,而且它被初始化为与int类型的对象v“绑定”在一起。此时r v叫做对象v的引用。

第3句把rv的值赋为3。引用的神奇之处就在这里,改变引用的值的同时也改变了和引用所绑定在一起的对象的值。所以此时v的值也变成了3。

第4句把v的值改为5,此时指向v的引用的值也被改成了5。所以第5句的中k的值是5+2等于7。

上述5句说明了引用及其绑定的对象的关系:在数值上它们是联动的,改变你也就改变了我,改变我也就改变了你。事实上,访问对象和访问对象的引用,就是访问同一块内存区域。

第6,7,8三句说明了引用的另一个特性:从一而终。什么意思?当你在引用的声明语句里把一个引用绑定到某个对象后,这个引用就永远只能和这个对象绑定在一起了,没法改了。所以这也是我用了“绑定”一词的原因。而指针不一样。当在指针的声明语句里把指针初始化为指向某个对象后,这个指针在将来如有需要还可以改指别的对象。因此,在第7句里把rv赋值为h,并不意味着这个引用rv被重新绑定到了h。事实上,第7句只是一条简单的赋值语句,执行完后,rv和

v的值都变成了12。第8句执行完后,rv和v的值都是20,而h保持12不变。

引用还有一个特性:声明时必须初始化,既必须指明把引用绑定到什么对象上。大家知道指针在声明时可以先不初始化,引用不行。所以下列语句将无法通过编译:

int v;

int &rv;

rv=v;

再举一例:

例二:

class MyClass

{

public:

int a;

...

...

};

MyClass myclass;

Myclass& cc=myclass;

myclass.a=20; //等价于cc.a=20

cc.a=60; //等价于myclass.a=60

从以上例子可以看到,无论这个对象有多复杂,使用该对象的引用或是使用该对象本身,在语法格式上是一样的,在本质上我们都使用了内存中的同一块区域。

取一个引用的地址和取一个对象的地址的语法是一样的,都是用取地址操作符"&"。例如:

int i;

int &ri;

int *pi=&ri;//这句的作用和int *pi=&i是一样的。

当然了,取一个对象的地址和取这个对象的引用的地址,所得结果是一样的。

二。引用在函数参数传递中的作用

现在让我们通过函数参数的传递机制来进一步认识引用。在c++中给一个函数传递参数有三种方法:1,传递对象本身。2,传递指向对象的指针。3,传递对象的引用。

例三:

class MyClass

{

public:

int a;

void method();

};

MyClass myclass;

void fun1(MyClass);

void fun2(MyClass*);

void fun3(MyClass&);

fun1(myclass); //执行完函数调用后,myclass.a=20不变。

fun2(&myclass); //执行完函数调用后,myclass.a=60,改变了。 fun3(myclass); //执行完函数调用后,myclass.a=80,改变了。

//注意fun1和fun3的实参,再次证明了:使用对象和使用对象的引用,在语法格式上是一样的。

void fun1(MyClass mc)

{

mc.a=40;

mc.method();

}

void fun2(MyClass* mc)

{

mc->a=60;

mc->method();

}

void fun3(MyClass& mc)

{

mc.a=80;

mc.method();

}

我们有了一个MyClass类型的对象myclass和三个函数fun1,fun2,fun3,这三个函数分别要求以对象本身为参数;以指向对象的指针为参数;以对象的引用为参数。

请看fun1函数,它使用对象本身作为参数,这种传递参数的方式叫传值方式。c++将生成myclass对象的一个拷贝,把这个拷贝传递给fun1函数。在fun1函数

内部修改了mc的成员变量a,实际上是修改这个拷贝的成员变量a,丝毫影响不到

作为实参的myclass的成员变量a。

fun2函数使用指向MyClass类型的指针作为参数。在这个函数内部修改了mc所指向的对象的成员变量a,这实际上修改的是myclass对象的成员变量a。

fun3使用myclass对象的引用作为参数,这叫传引用方式。在函数内部修改了mc的成员变量a,由于前面说过,访问一个对象和访问该对象的引用,实际上是访问同一块内存区域,因此这将直接修改myclass的成员变量a。

从fun1和fun3的函数体也可看出,使用对象和使用对象的引用,在语法格式上是一样的。

相关文档
最新文档