这篇文章写的很杂,因为我查阅多方资料,呵呵,也没时间整理,所以大家就当是看意识流的吧。哈哈

首先来说说指针的引用如何赋予初值吧,我之前很简单的认为可以这样写,大家看下面的例子:



1
2 CFbsBitmap*& aBackgroudBitmap= NULL;
但是这样写是有问题的。我当时请教高手的时候人家说是c语言历史遗留下来的问题,
我也没搞清楚,那位大神要是明白的话麻烦说一下。
但是我知道,可以通过下面的形式赋予初值。
1 typedef int* A;
2 A oo;
3 A & ooo = oo;

我一般都是这样写的,哈哈,

接下来说说两者在释放内存方面的区别吧,看代码:



1 #include <iostream>
2 using namespace std;
3 void freePtr1(int* p1)
4 {
5    delete p1;
6    p1 = NULL;
7 }
8 void freePtr2(int*& p2)
9 {
10    delete p2;
11    p2 = NULL;
12 }
13
14 void main()
15 {
16    int *p1 = new int;
17    *p1 = 1;
18    freePtr1(p1);
19    int *p2 = new int;
20    *p2 = 2;
21    freePtr2(p2);
22    system("pause");
23 }
24 思考:在freePtr1和freePtr2 的比较中,你能发现它们的不同点吗?
25
26 二、对代码进行解释:
27 #include <iostream>
28 using namespace std;
29 void freePtr1(int* p1)
30 {
31    //未释放内存前 ->  p1 Address : 0012FDDC  p1 value : 003429B8,在这里,p1它也是一个变量,既然是一个变量,那么它将会以值的传递,把外部变量p1传到栈内,在栈内产生一个地址:0012FDDC,当然,它的值不会变仍然是指向堆地址:003429B8 。
32    delete p1; //系统回收p1值的地址003429B8处的内存。
33 p1 = NULL;//对p1赋以NULL值即:00000000,注意:p1本身的地址并没有变,变的是p1的值。
34    //释放内存后 ->  p1 Address : 0012FDDC  p1 value : 00000000,出栈后,p1由于是一个临时对象,出栈后它会自动被视为无效。
35 }
36 void freePtr2(int*& p2)
37 {
38    //未释放内存前 ->  p2 Address : 0012FEC8  p2 value : 003429B8,p2是一个指针的引用,即引用指向指针,记住引用的特点:对引用的对象直接操作。所以它的地址和值与栈外的main()函数中,p2的值是同一个。
39    delete p2; //对p2所引用的指针进行释放内存,即:系统回收main()函数中 p2的值 003429B8 地址处的内存。
40    p2 = NULL;//对main()函数中p2的指针赋以NULL值。
41    //释放内存后 ->  p2 Address : 0012FEC8  p2 value : 00000000,由于操作的对象都是main()函数中的p2,所以它将应用到原变量中。
42 }
43
44 void main()
45 {
46    int *p1 = new int;
47 //释放内存前->  p1 Address : 0012FED4  p1 value : 003429B8
48    freePtr1(p1);
49    //释放内存后->  p1 Address : 0012FED4  p1 value : 003429B8
50
51    int *p2 = new int;
52    //释放内存前->  p2 Address : 0012FEC8  p2 value : 003429B8
53    freePtr2(p2);
54    //释放内存后->  p2 Address : 0012FEC8  p2 value : 00000000
55    system("pause");
56 }

实际上你可以想象成 Int*&为 int **,所以内部当然可以修改他的值!但是**和*&,语义上是有区别的,但不少编译器却把两者等同对待,产生的代码是一样的(比如vc,可以disassemble瞧瞧),不过常常有先生指导咱后生在c++里能用&尽量不要用*,呵呵,遵照了便是 。

无论你传值还是传指针,函数都会生成一个临时变量,

但传递一个指针的引用时,不会生成临时变量~~~

传递指针和采用指针的引用,他们中间的具体实现过程是有所不同的。

参数传递指针时将直接对指针指向的地址进行操作

传递指针的引用时,通过间接寻址,来实现对[指针指向的地址]进行操作。

因为我们传指针,目的是在函数外面获得在函数里面改变的指针所指对象的值


而指针的引用,目的是在函数外面获得在函数里面改变的指针本身的值

看个例子:



1 #include   <iostream>
2 using   namespace   std;
3
4 void   f1(int   *&a)
5 {
6         int   *b;
7         b=a;
8 }
9
10 void   f2(int   *a)
11 {
12         int   *b;
13         b=a;
14 }
15
16 void   main()
17 {
18         int   m=10;
19         int   *n=&m;
20
21         f1(n);
22         f2(n);
23
24 }
25 //---------------------------------------------------------------------------
26
27
28 *   Referenced   by   a   CALL   at   Address:
29 |:00401187
30 |
31 :00401150   55                                             push   ebp
32 :00401151   8BEC                                         mov   ebp,   esp
33 :00401153   51                                             push   ecx
34 //[ebp+08]即为压栈内容:n的有效地址
35 :00401154   8B4508                                     mov   eax,   dword   ptr   [ebp+08]
36 //取得主函数中m的有效地址--》edx
37 :00401157   8B10                                         mov   edx,   dword   ptr   [eax]
38 //b=a;
39 :00401159   8955FC                                     mov   dword   ptr   [ebp-04],   edx
40 :0040115C   59                                             pop   ecx
41 :0040115D   5D                                             pop   ebp
42 :0040115E   C3                                             ret
43
44
45 *   Referenced   by   a   CALL   at   Address:
46 |:00401190
47 |
48 :00401160   55                                             push   ebp
49 :00401161   8BEC                                         mov   ebp,   esp
50 :00401163   51                                             push   ecx
51 //取得压栈内容:n的有效内容(即m的有效地址)
52 :00401164   8B4508                                     mov   eax,   dword   ptr   [ebp+08]
53 //b=a;
54 :00401167   8945FC                                     mov   dword   ptr   [ebp-04],   eax
55 :0040116A   59                                             pop   ecx
56 :0040116B   5D                                             pop   ebp
57 :0040116C   C3                                             ret
58
59
60 ---------------> 函数开始 <----------------------------
61 :00401170   55                                             push   ebp
62 :00401171   8BEC                                         mov   ebp,   esp
63 :00401173   83C4F8                                     add   esp,   FFFFFFF8
64 int   m=10;
65 :00401176   C745FC0A000000                     mov   [ebp-04],   0000000A
66 int   *n=&m;
67 :0040117D   8D45FC                                     lea   eax,   dword   ptr   [ebp-04]
68 :00401180   8945F8                                     mov   dword   ptr   [ebp-08],   eax
69 f1(n);
70 //由于形参是引用变量,所以将n的有效地址压栈
71 :00401183   8D55F8                                     lea   edx,   dword   ptr   [ebp-08]
72 :00401186   52                                             push   edx
73 :00401187   E8C4FFFFFF                             call   00401150
74 :0040118C   59                                             pop   ecx
75 f2(n);
76 //由于形参是指针变量,所以将n的有效内容压栈(即m的有效地址)
77 :0040118D   FF75F8                                     push   [ebp-08]
78 :00401190   E8CBFFFFFF                             call   00401160
79 :00401195   59                                             pop   ecx
80 :00401196   59                                             pop   ecx
81 :00401197   59                                             pop   ecx
82 :00401198   5D                                             pop   ebp
83 :00401199   C3                                             ret
84

呵呵。大家还有什么高见多多留言啊,以上几处代码来自互联网,由于比较杂,本人整理的,所以不好写出处,忘原作者见谅啊、