weiqi7777

c++ reference研究

1
阅读(1671)

c++相比于c语言,增加引用(reference)语法。这样的话,可以在函数调用,传引用,也可以实现函数内部修改外部参数值。而避免使用指针。

之前,对这个引用,没有特别的理解,但是看了侯捷老师的视频之后,会这个突然就恍然大悟了。

视频链接如下:

        https://www.bilibili.com/video/av27135524?p=28

侯捷老师,在讲解引用时,有提到,引用,就是漂亮的指针。功能和指针一样,但是使用起来更漂亮。

我们在写程序时,一般会认为,对于一个变量,会分配内存空间,对于引用定义的变量,我们也认为会分配内存空间。

比如如下代码:

int a = 5;

int &b = a;

int &c = b;

定义了3个变量,a,b,c,其中b和c是通过引用定义的。我们一般认为,编译器,会为a,b,c三个变量,都分配内存空间,然后通过特殊的操作,使的三个变量的操作,均是一致的。

但是,侯捷老师讲解到,对于引用定义的变量,其实并没有分配内存空间,使用的地址,和引用的变量是同一个地址。其实引用变量,就是被引用变量的一个别名。但是,它却给我们了一种,会为引用定义变量,分配的空间的这样一种假象。

侯捷老师,在这里原话解释是:

object(引用定义变量)和其reference的大小相同,地址也相同(全都是假象)

因此,可以通过下面这个代码,进行印证。

int test(int a) {

printf("test a address: %x\n", &a);

return 0;

}

 

int test1(int& a) {

printf("test1 a address: %x\n", &a);

return 0;

}

 

int main()

{

int a = 5;

int &b = a;

int &c = b;

printf("a address: %x\n", &a);

printf("b address: %x\n", &b);

printf("c address: %x\n", &c);

test(a);

test1(a);

}

在main函数中,定义了a,b,c三个变量,其中b和c是引用定义的变量,均引用到a。

将a,b,c的地址,打印出来。

a address: 6dfef4

b address: 6dfef4

c address: 6dfef4

从打印输出,可以看出,a,b,c三个变量的地址其实是一样的。正是因为他们的地址是一样的,所以对其中任意一个操作,也同样改变了其他的变量。所以,编译器,对于引用定义的变量,并不会分配内存空间,而是直接使用引用变量的内存地址空间。

下面看一下函数参数,传递为变量,和引用的却别。

int test(int a) {

printf("test a address: %x\n", &a);

return 0;

}

int test1(int& a) {

printf("test1 a address: %x\n", &a);

return 0;

}

int main()

{

int a = 5;

printf("a address: %x\n", &a);

test(a);

test1(a);

}

test函数,传递的是变量,test1函数,传递的是引用。

在函数内部,分别将参数的地址给打印出来。

打印结果如下:

a address: 6dfefc

test a address: 6dfee0

test1 a address: 6dfefc

可以看出,函数参数传引用的话,那么该引用变量的地址,和外部传参变量的地址是一样的,所以这也是为什么,函数传递引用,在函数内部读该引用变量修改,就可以直接修改外部传参变量的值。因为,他们就是操作的同一片地址空间。

侯捷老师,在课程中一直提到,在c++中,函数参数传递,尽量使用引用,因为这会比较快。

原因就在于,传递引用,编译器只是将地址传递过去,如果是传递参数,那么编译器,会为参数分配一个新的内存空间,然后把传递参数的值,原封不动的拷贝进去,这样的话,效率就低了。如果是一个简单类型变量,那还能接受,如果是一个结构体,或者是个类,那么这里的拷贝,可能就会降低效率了。

所以对于引用的理解,就认为引用,就是原变量的别名就好。他们的地址空间完全一致。