C++ 与指针
1.先看下面两段代码的运行结果
(1)

(2)

二、原理分析
1、示例一分析:
起初C++没有自己的编译器,它是使用C语言编译器进行编译的。所以,在实现C++的类的时候,采用的是结构体来实现的。而实现成员函数和类的关系的时候,是靠着this指针来调用成员函数的。具体来说,就是在其成员函数的第一个默认参数设置为对应类型的this指针。
比如,void fun()就被改成void fun(CTest *this)。那么这句调用ptr->fun()就会被转换成fun(ptr)。这样一来,fun函数就可以当成普通的函数来处理了。所以,在调用fun函数的时候直接在全局的符号表里查找就好。这么说的话,那第一个无疑就可以正常输出了。
那么,CTest要是有数据成员data,并且,我们能不能靠this指针输出这个数据成员呢?答案当然是否定的。因为ptr->data等价于(*ptr).data,ptr又是指向为空,所以,程序会因为(*ptr)发生空指针异常而崩溃。
2、示例二分析:
由于,fun()函数是虚函数,所以,fun()函数的符号地址是存在一个虚函数表中。所以,我们调用虚函数时,得在对应的虚函数表中查找它的符号地址。而虚函数表的地址,是靠一个指针来存储的,该指针位于该类实例化对象的起始部分。具体关系如下图所示:

首先,站在对象的角度来说,没有对象就没有这个虚表指针了,也就不能去访问虚函数表和虚函数表上面记录的虚函数的符号地址了。
其次,站在指针的角度来说,指针的本身只是一个变量,它里面存储的地址值只是标示了它在找被指向单元时,应该从哪里开始找,而它的类型只是标示了得连续找多少字节。也就是说,ptr = NULL说明了ptr所指向的对象的起始地址值是0。在进行虚函数表访问fun()函数的符号表的时候,它的过程类似于(ptr->v_ptr)->fun()。所以,ptr->v_ptr这句也会引起空指针空指针异常而产生程序崩溃。

浙公网安备 33010602011771号