写点啥呢?既然是个C++的空指针问题,那就写一个多年前帮一个新手C++程序员的剖析案例吧,重点不是代码,而是这个代码背后的缘故原由,以是我就用一个大略的样例来还原一下小哥哥当时出的问题吧,我到现在都记得问题缘故原由说完后他那一脸懵逼的表情。

先贴下代码截图:

有一个ItemClass的类,里面有一个Say的方法

在jsp中只有一行代码明明是个C的空指针它为啥挪用办法不报错呢 RESTful API

然后我在主入口那里实行以下代码:

神奇的事情发生了,它没报错。

如果不想理解过程,只想快速知道答案,就翻到最下面吧。

剖析把稳点

这个问题看似不合理,一个空指针工具,都还没有分配内存,你说调用就调用,调用就算了,你还不挂,还有没有天理了?

如果对编译事理轻微理解一点,这个问题也算是好理解吧。
当时包括我自己都没有把稳到Say这个方法的分外点,差一点就给带进去了。
在给出结论前,我们须要就办理该问题所要关注的几个重点事变解释一下:

ItemClass这个类在编译的时候天生了二进制代码,代码构造有兴趣可以去查一下,这里不当重点讲了,我们讲这个Say方法,它在全体类编译完后是放在了代码段,也便是.text段里面,全体代码文件放到了硬盘上,在实行程序的时候从硬盘加载到内存当创建一个ItemClass类的指针的时候,先不管给指针分配内存的问题,至少指针指向的是一个什么类型已经是明确了,便是ItemClass,这里也不去聊什么多层继续的问题,大略点重点来了,这个指针啥也没干,赋了个空值,然后去调用了这个方法,然后方法还实行了

实行过程

大略描述下过程:

ItemClass通过入口程序从硬盘上被加载到内存,所有的成员变量、常量、静态变量、方法会被加载进来main函数加载到栈上,pItemClass作为方法的内部变量,也存放在栈上,但是赋为null

此时实行pItemClass->Say()方法时,系统会从加载到内存的ItemClass二进制代码段找到Say方法的代码,然后实行个中的二进制代码Say方法中实在只有一行代码,便是打印一个字符串,把稳,此时该方法中没有与类实例绑定的变量的调用,也便是说这个Say方法中没有调用ItemClass类中的须要初始化ItemClass类工具才能访问的变量。
由于没有,以是全体代码不须要访问特定pItemClass指针指向的那块堆内存中的某个变量的值(这个问题中,pItemClass没指向存放ItemClass实例的堆内存,由于还没分配),既然没有,那么系统实行的时候就不会去堆上找特定工具的干系变量的值,反正不找,空指针也无妨,自然就不会报错最关键的点:编译器天生代码的时候,如果方法中包含了类的成员变量,编译器会在该成员变量前加上this->,比如在ItemClass中加一个成员x,然后在Say方法中去访问这个x,则运行报错,由于编译后的代码在访问x时就变成了this->x,改一下再运行看看:

加一个x成员变量

重新运行结果

看到了吗?报了个this,谁瞥见this了,那便是由于编译器加上去的。

好了,根据这个事理,我们实在可以对静态成员、常量再做下测试,运行看是什么结果。

形象阐明

这个问题就彷佛买商品房,屋子空调是选装的(成员变量x,须要上去看下倒数第二张图),别杠,说空调是必装的。
窗户是必装的(别杠说没窗户,杠便是那东北傻狍子),就像最开始的Say方法里面那个输出字符串的代码。
此时买主还没签完条约,现在开拓商想给屋子通个风,他要实行透风的动作,你这时候去打开窗户是没问题的,买主没买那窗户也在那。
现在如果实行透风的动作要去打开空调,对不起,报错,压根没空调,此时的屋子没主人,就像那个pItemClass没分配内存创建工具一样,屋子没指向买主,你打开谁的空调?那啥时候不报错?买主买了屋子,他装修屋子(pItemClass终于初始化了)装了空调,这时候物业如果检讨屋子再实行透风动作去打开买主装的空调,就没问题了,由于空调已经装好了。

好了,罗里吧嗦又写了一篇,心情惬意很多,回去连续看那个问题去,搞不好同事已经办理了。
还是要说一下:

懂事理真的很主要,很多知识实在是由事理产生的不同领域的知识很多时候是可以平行迁移来进行相互阐明和学习的

好,就写到这,干活去了,后面还得连续更新我的PG系统了