C++中引用、指针的指针、指针的引用解析

来源:互联网 发布:寻秦ol源码 编辑:程序博客网 时间:2024/04/26 17:01

本文为znd8866原创,转载请注明出处。

由于本人功力有限,有错误之处恳请指正,谢谢。

(1)这样写为什么会错?

看下面一段程序:

void Fun1 (MyClass *ptr)

{

       ptr=(MyClass*)malloc(MyClass);//或者用new来分配:ptr=new MyClass()

}

MyClass *p=new MyClass();

Fun1(p);

会发生什么情况呢?

首先编译器会分配一个MyClass空间,并在栈上创建指针p,它指向创建的MyClass空间:

然后调用Fun1函数,Fun1函数会创建一个新的MyClass类型的指针ptr,它的值既是p的值,它也指向创建的MyClass对象:

然后Fun1函数调用malloc函数,它向系统申请一个新的MyClass空间,将新的MyClass空间的首地址赋给ptr:

相信读者现在已经看出来了,是的,他最终变成了下面的形式:

也就是说,调用函数Fun1后,指针p的值并没有改变,它与调用前没有任何区别。但我们的意图是让Fun1分配新的存储空间给指针p,这显然达不到我们的期望,那么应当怎么做呢?

在不改变函数Fun1返回值的情况下,有两种方法:

(1)   使用指针的指针

(2)   使用指针的引用

(2)指针的指针

看下面的程序:

void Fun1 (MyClass **ptr)

{

       *ptr=(MyClass*)malloc(MyClass);

}

MyClass *p=new MyClass();

Fun1(&p);

会发生什么情况呢?

首先,编译器会分配一个MyClass空间,并在栈上创建指针p,它指向创建的MyClass空间:

图中0x00EEBBDD是p指针在栈上的地址。

然后调用Fun1函数。首先,函数Fun1会创建一个指针的指针ptr,它指向的指针指向MyClass类型,它的值即p指针的地址0x00EEBBDD,如下图:

然后,Fun1调用malloc函数,它向系统申请一个新的MyClass内存空间,将这个新的空间的首地址赋给*ptr,注意是*ptr而不是ptr,*ptr就是p的值,即p的值被改变:

从图中可以看出,p的值被改变,他指向了新的空间,达到了我们的期望,但要注意这样会发生内存泄露,即原来分配的0x00FF44DD内存没有释放,这可以在分配内存前先释放原内存来解决,或者使用下面讲的引用。

(3)引用

记住一点:凡是对变量的引用的改变都是对变量本身的直接改变。

这里我们不讨论引用是否占用内存空间(许多书上都说引用不占内存空间,但如果你仔细观察反汇编代码的话,其实引用是占内存空间的),也不讨论编译器对引用的处理(其实编译器是把引用翻译为指针常量的,指针的值不可以改变,但指针指向的变量的值可变),我们仅讨论引用的特性及应用。

引用相当于变量的别名,改变引用就相当于改变变量本身,引用在使用上是和变量等价的。

例如:

void fun (int &a,int &b)

{

       inttemp=a;

       a=b;

       b=temp;

}

int i=3,j=4;

fun (i,j);

会发生什么呢?

在调用fun函数时,首先fun函数会为变量i、j分别创建引用a、b,如下:

从这里就可以看出,如果改变a、b的值,就可以直接改变i、j的值。

(4)指针的引用

到此问题就变得很简单了,在使用指针的引用时,就相当于使用指针本身。

看下列代码:

void Fun1 (MyClass *&ptr)

{

       ptr=(MyClass*)malloc(MyClass);//或者ptr=new MyClass();

}

MyClass *p=new MyClass();

Fun1(p);

会发生什么呢?

首先,编译器会分配一个MyClass空间,并在栈上创建指针p,它指向创建的MyClass空间:

然后调用Fun1函数,Fun1函数会创建一个指针p的引用ptr,如下所示:

相信读者已经看出来了,ptr的值就是p的值,改变ptr的值就是对p的值的直接改变。

至此对指针与引用的讨论结束。


10 0
原创粉丝点击