《C++ Primer》引用和指针

来源:互联网 发布:mac安装ttf字体 编辑:程序博客网 时间:2024/05/21 18:45

学习C++的时候,我越来越感觉如果没有真正学会引用和指针,那么其他的部分就非常难以理解。因此,对于C++来说,引用和指针是绝对基础而又重要的。

引用


我们可以想象一下,对门王奶奶养了一只加菲猫,王奶奶给这只猫起名字叫“球球”。那么,“球球”就是“王奶奶的加菲猫”这个对象的引用。由此引出了引用的定义:引用为对象起了另外一个名字,通过将生命付写成&d的形式来定义引用类型,其中d是声明的变量名。

我们再想,对于王奶奶来说,“球球”这个名字已经给了她家的猫,不可能再管家里的桌子、电视机叫“球球”,也就是说“球球”和那只猫是绑定在一起的。因此,“球球睡着了”就意味着那只猫睡着了,“球球醒了”就意味着那只猫醒了,“睡着”和“醒”都是那只猫的状态,而不是“球球”这个词的状态。到这里,我们其实也就知道了另外一点,单单“球球”这个词是毫无意义的,“球球”必须和那只猫联系起来,“球球”这个词才有意义。

所以,《C++ Primer》总结了三点:
1. 定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用。
2. 一旦初始化完成,引用将和它的初始值对象一直绑定在一起。
3. 因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。(这里,我觉得是因为单单一个别名没有意义,所以引用必须初始化) 。

既然是自己家里的猫,王奶奶一定会给家里的猫下命令,比方说,“球球你不要乱咬东西”。虽然说王奶奶是叫“球球”不要乱咬东西,但实际上是叫那只猫不要乱咬东西,而不是“球球”这个词不要乱咬东西。另外,王奶奶一定不会把“不要乱咬东西”起名叫“球球”。

由此,又能得到两点:
1. 为引用赋值,实际上是把值赋给了与引用绑定的对象。获取引用的值,实际上是获取了与引用绑定的对象的值。同理,以引用作为初始值,实际上是以与引用绑定的对象作为初始值。
2. 引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。


指针


指针相对于引用就不是那么好理解。可以想象一下,Tom住在宾馆2048号房间,那么这个2048号房间就是Tom所在的地址。比方说lodger(房客)是一个变量,lodger这时就是Tom, 那么&lodger这个操作就代表的是2048这个房间号。某一天,酒店说,我要加强酒店的管理,我得招聘一个管理员,他可以随意处置某个房间里的一切,不用管房客同不同意。这个管理员就是指针。这一次,管理员pr_Tom被分配到管理Tom的房间,我们就会使用pr_lodger = &lodger这个语句来表示。*号用来解除指针,*pr_lodger就代表pr_lodger管理的房间号里住着的人。由于房间管理员级别很高,他可以随意处置房客,如果他认为Peter应该住进2048号房间,也就是*pr_lodger = Peter,那么这块地方Tom就不能住了,房客也就变成了Peter。也就是说,lodger这个变量的值现在是Peter。

上面说的是正常的情况,也就是说管理员只是对普通房客行使自己的权利,一切都还好说,但是问题在于这个管理员的权力太大,而且比较死脑筋,如果因为某种失误导致管理员指向了重要客户的房间甚至酒店管理层的房间,管理员再随意行使权力,那么后果就是不堪设想的。因此使用指针这个管理员的时候必须要小心。在管理员没什么事做的时候,一定要告诉他你哪里都不要指(nullptr)。

到了这里,我觉得可以先总结一下:
1. 指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。
2. 指针无须在定义时赋初值,如果没有初始化,将拥有一个不确定的值。
3. 获取某对象地址使用取地址符(&)。
4. 指针的值有四种:(指向一个对象、指向紧邻对象所占空间的下一位置、空指针、无效指针)。
5. 如果指针指向了一个对象(⚠️一定要确保这一点),允许使用解引用符(*)来访问该对象。
6. 可以使用NULL或者0代表空指针,C++11 以后可以使用nullptr,我更倾向于使用nullptr。
7. ⚠️一定要确保指针的使用是合法的,也就是说,指针最好在使用之前初始化为空指针,并且在使用过程中随时注意指针的使用状况,多对指针加以限制(最典型的,const)。

void*指针的特点
1. 可用于存放任意对象的地址。
2. 我们对该地址中到底是什么类型的对象并不了解。
3. 不能直接操作void*指针所指的对象,因为我们并不知道这个对象到底是什么类型,也就无法确定能在这个对象上做那些操作。

void*指针的用途
1. 拿它和别的指针比较。
2. 作为函数的输入或输出。
3. 赋给另外一个void*指针。


0 0
原创粉丝点击