引用类型(c++变量类型)

由类型的实际值引用(类似于指针)表示的数据类型。如果为某个变量分配一个引用类型,则该变量将引用(或“指向”)原始值。不创建任何副本。引用类型包括类、接口、委托和装箱值类型。

基本内容

由类型的实际值引用(类似于指针)表示的数据类型。如果为某个变量分配一个引用类型,则该变量将引用(或“指向”)原始值。不创建任何副本。引用类型包括类、接口、委托和装箱值类型。

一些计算机高级语言有引用类型这种变量类型。

一、C语言中没有引用类型。

二、C++中的引用类型:

“引用”(reference)是c++的一种新的变量类型,是对C的一个重要补充。它的作用是为变量起一个别名。假如有一个变量a,想给它起一个别名,可以这样写:

int a;int&b=a;

这就表明了b是a的“引用”,即a的别名。经过这样的声明,使用a或b的作用相同,都代表同一变量。在上述引用中,&是“引用声明符”,并不代表地址。

不要理解为“吧a的值赋给b的地址”。声明引用并不开辟内存单元,b和a都代表同一变量单元。

注意:在声明引用变量类型时,必须同时使之初始化,及声明它代表哪一变量。在声明一个变量的引用之后,在本函数执行期间,该引用一直与其代表的变量相联系,不能再作为其他变量的别名。下面的用法不对:

int a1,a2;

int&b=a1;

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

例1:

#include

#include

void main()

{

int a=10;

int&b=a;//声明b是a的引用,这样a的值变以后,b的值也变;b的值变以后,a的值也跟着变。

a=a*a;

cout<

b=b/5;

cout<

}

有了变量名,为什么还需要一个别名呢?C++之所以增加“引用”,主要是把它作为函数参数,以扩充函数传递数据的功能。

我们知道,在C语言中,函数参数传递是单向的,所以例4不能实现两个变量值的交换。C语言中,数组作为函数参数传递的是数组的首地址。

C语言中,还可以利用指针变量做形参来实现两个变量值的换,但这种方式需要定义指针变量,需要额外开辟存储空间,来存放地址,见例3。而引用变量不是独立的变量,不单独占内存单元这种方法,实参向形参传送的是实参的地址(但与指针不同的是掉用函数时不需要&),而不是实参的值,见例2。

看到&a这种形式时,怎样区分是指针还是引用呢?一般而言,见到前面有类型说明符(如int&a),是引用,而前面没有类型说明符时(如&a)认为是指针。

例2:

//函数参数传递之引用调用

#include

void swap(int&a,int&b)

{

int temp;

temp=a;

a=b;

b=temp;

}

void main()

{

int i=3,j=5;

swap(i,j);

cout<<"i="<

cout<<"j="<

}

例3:

//函数参数传递之传地址调用(通过指针)

#include

void swap(int*a,int*b)

{

int temp;

temp=*a;

*a=*b;

*b=temp;

}

void main()

{

int i=3,j=5;

swap(&i,&j);

cout<<"i="<

cout<<"j="<

}

例4:

//错误程序例:这个程序不能实现i和j值的交换。

#include

void swap(int a,int b)

{

int temp;

temp=a;

a=b;

b=temp;

}

void main()

{

int i=3,j=5;

swap(i,j);

cout<<"i="<

cout<<"j="<

}

备注:注意C++中引用类型与类的区别。

参考文献:东北大学出版社-李一波编着《新概念C语言》218页

清华大学出版社陈天华编着《面向对象程序设计与VisualC++教程》73页

三、C#中也有引用类型。

区别

看实例吧:

引用是C++中的概念,初学者容易把引用和指针混淆一起。

下面的程序中,n是m的一个引用(reference),m是被引用物(referent)。

int m;

int&n=m;

n相当于m的别名(绰号),对n的任何操作就是对m的操作。

所以n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。

引用的规则

(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。

(2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。

(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。

以下示例程序中,k被初始化为i的引用。

语句k=j并不能将k修改成为j的引用,只是把k的值改变成为6。

由于k是i的引用,所以i的值也变成了6。

int i=5;

int j=6;

int&k=i;

k=j;//k和i的值都变成了6;

主要功能

在C++中可以定义“引用”。定义方式如下:类型名&引用名=同类型的某变量名;

引用的主要功能:传递函数的参数和返回值。

C++语言中,函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递。

以下是"值传递"的示例程序。

由于Func1函数体内的x是外部变量n的一份拷贝,改变x的值不会影响n,所以n的值仍然是0。

void Func1(int x)

{

x=x+10;

}

int n=0;

Func1(n);

cout<<"n="<<n="0"n="0;"n="<<n<<endl;//n=10以下是"size="14">

void Func3(int&x){x=x+10;}…int n=0;Func3(n);cout<<"n="<<n="10">

(1)在实际的程序中,引用主要被用做函数的形式参数–通常将类对象传递给一个函数.引用必须初始化.但是用对象的地址初始化引用是错误的,我们可以定义一个指针引用。

1int ival=1092;

2int&re=ival;//ok

3int&re2=&ival;//错误

4int*pi=&ival;

5int*&pi2=pi;//ok

(2)一旦引用已经定义,它就不能再指向其他的对象.这就是为什么它要被初始化的原因。

(3)const引用可以用不同类型的对象初始化(只要能从一种类型转换到另一种类型即可),也可以是不可寻址的值,如文字常量。例如:

double dval=3.14159;

//下3行仅对const引用才是合法的

const int&ir=1024;

const int&ir2=dval;

const double&dr=dval+1.0;

上面,同样的初始化对于非const引用是不合法的,将导致编译错误。原因有些微妙,需要适当做些解释。

引用在内部存放的是一个对象的地址,它是该对象的别名。对于不可寻址的值,如文字常量,以及不同类型的对象,编译器为了实现引用,必须生成一个临时对象,引用实际上指向该对象,但用户不能访问它。

例如:

double dval=23;

const int&ri=dval;

编译器将其转换为:

int tmp=dval;//double->int

const int&ri=tmp;

同理:上面代码

double dval=3.14159;

//下3行仅对const引用才是合法的

const int&ir=1024;

const int&ir2=dval;

const double&dr=dval+1.0;

内部转化为:

double dval=3.14159;

//不可寻址,文字常量

int tmp1=1024;

const int&ir=tmp1;

//不同类型

int tmp2=dval;//double->int

const int&ir2=tmp2;

//另一种情况,不可寻址

double tmp3=dval+1.0;

const double&dr=tmp3;

(4)不允许非const引用指向需要临时对象的对象或值,即,编译器产生临时变量的时候引用必须为const!!!!切记!!

int iv=100;

int*&pir=&iv;//错误,非const引用对需要临时对象的引用

int*const&pir=&iv;//ok

const int ival=1024;

int*&pi_ref=&ival;//错误,非const引用是非法的

const int*&pi_ref=&ival;//错误,需要临时变量,且引用的是指针,而pi_ref是一个非常量指针

const int*const&pi_ref=&ival;//正确

//补充

const int*p=&ival;

const int*&pi_ref=p;//正确

(5)********对于const int*const&pi_ref=&iva;具体的分析如下:*********

1.不允许非const引用指向需要临时对象的对象或值。

int a=2;

int&ref1=a;//OK.有过渡变量。

const int&ref2=2;//OK.编译器产生临时变量,需要const引用

2.地址值是不可寻址的值。

int*const&ref3=&a;//OK;

3.于是,用const对象的地址来初始化一个指向指针的引用。

const int b=23;

const int*p=&b;

const int*&ref4=p;

const int*const&ref5=&b;//OK

const引用的语义到底是什么?

最后,我们可能仍然不明白const引用的这个const的语义是什么。const引用表示,试图通过此引用去(间接)改变其引用的对象的值时,编译器会报错!这并意味着,此引用所引用的对象也因此变成const类型了。我们仍然可以改变其指向对象的值,只是不通过引用。下面是一个简单的例子:

1#include

2using namespace std;

3

4int main()

5{

6int val=1024;

7const int&ir=val;

8

9val++;

10//ir++;

11

12cout<<"val="<

13cout<<"ir="<

14return0;

15}

其中第10行,如果我们通过ir来改变val的值,编译时会出错。但是我们仍然可以通过val直接改变其值(第9行)

总结:const引用只是表明,保证不会通过此引用间接的改变被引用的对象!

另外,const既可以放到类型前又可以放到类型后面,放类型后比较容易理解:

string const*t1;

const string*t1;

typedef string*pstring;string s;

const pstring cstr1=&s;就出错了

但是放在类型后面不会出错:

pstring const cstr2=&s;

该文章由作者:【猩猩影视】发布,本站仅提供存储、如有版权、错误、违法等相关信息请联系,本站会在1个工作日内进行整改,谢谢!

发表回复

登录后才能评论