如果一个对象的指针p是NULL,通过p->SomeFunction()的形式调用成员函数。是否会出错?
答案是调用本身不会出错,函数内部是否会出错取决于是否会直接或间接访问成员变量。可以参考下面的例子代码。如果把CDemo* p1 = NULL;改成CDemo* p1 = new CDemo就不会有错误了。
Example
class CDemo { public: void DoNotAccessMember() { printf("Do Not Access Memeber variable. Class pointer = %x/r/n", this); } void AccessMember() { printf("Access Memeber variable. Class pointer = %x/r/n", this); int i = m_i; //Access this->m_i error printf("After access Memeber variable. Class pointer = %x/r/n", this); } private: int m_i; }; int main(void) { try { CDemo* p1 = NULL; p1->DoNotAccessMember(); printf("DoNotAccessMember sucessfully/r/n"); p1->AccessMember(); printf("AccessMember sucessfully/r/n"); } catch(...) { printf("Access exception/r/n"); } return 0; }
Display
Do Not Access Memeber variable. Class pointer = 0 DoNotAccessMember sucessfully Access Memeber variable. Class pointer = 0 Access exception
Reason
根本原因与C++对象的生成方式有关。C++编译器会为每一个对象分配独立的数据空间。也就是同一个类的不同对象的成员变量各自独立。但是,所有的对象会共享一个类的函数入口表。区分调用函数的具体对象的方式,使编译器自动把对象指针隐式传递给每一个成员函数作为参数,也就是this。对于pointer->function(),pointer的值会传给function;对于object.function,object的的地址会传给function。所以,即使pointer是一个无效指针,如果没有访问成员变量,是不会出错的。但是当试图访问成员变量时,this->variable指向了无效内存地址,就会遭成内存访问异常。