对象指针为NULL,为什么还是可以调用成员函数

本文深入探讨了C++中成员函数的工作原理,包括通过NULL对象指针调用成员函数的行为及后果,并解释了虚函数调用的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

B
要理解这个的话。。。成员函数其实可以认为是一个普通的函数,比如
1
2
3
4
class A{
public:
    void func(int x) { cout<<"hello, A. x="<<x<<endl; }
};

在编译器看来,大概就长这个样子吧:

1
void A_func(A* this, int x) { cout<<"hello, A. x="<<x<<endl; }

你平时使用成员函数的时候,大概就是这样的:

1
2
A a;
a.func(2);

其实在编译器看来,是这个样子的:

1
A_func(&a, 2);

如果这么说的话,也许你就理解了,为什么对象是NULL的时候还可以调成员函数:

1
2
3
4
5
6
A *pa = NULL;
pa->func(2);
//在编译器看来就好像是 A_func(pa, 2);且pa==NULL
 
((A*)NULL)->func(2);
//在编译器看来就好像是 A_func( ((A*)NULL), 2);

-----我是分割线-----

上面的例子中func函数里并没有使用成员变量。考虑有成员变量并且在成员函数里使用的情况,就会不一样了:

1
2
3
4
5
6
class A{
private:
    int y;
public:
    void func(int x) { y = x; }
};

注意此时y是成员变量,编译器会自动给它加上this->,也就是

1
void A_func(A* this, int x) { this->y = x; }

此时正常的情况就不用说了,说说用NULL对象指针调用成员函数的情况:

1
2
3
4
5
6
7
8
A *pa = NULL;
pa->func(2);
//在编译器看来就好像是 A_func(pa, 2);且pa==NULL
 
((A*)NULL)->func(2);
//在编译器看来就好像是 A_func( ((A*)NULL), 2);
 
//好吧我承认这段代码跟上面的一毛一样啦!

此时程序会崩溃!为什么?因为this指针是NULL,而你访问了它的y变量!

----又是我哈哈哈-----

结论:

  1. 通过对象调用成员函数,对象的指针会被传入函数中,指针名称为this

  2. 因此NULL对象指针也可以调用成员函数

  3. NULL对象指针调用成员函数时,只要不访问此对象的成员变量,则程序正常运行

  4. NULL对象指针调用成员函数时,一旦访问此对象的成员变量,则程序崩溃

下面是我加的
同理,当在调用虚函数时,对于一个虚拟函数调用
如b->FunctionB();
将会被转化成 (*b->vptr[1])(b),vptr表示由编译器产生的指针,指向virtual table,而1是virtual table slot的索引值,关联到FunctionB函数,此时b为NULL,因此肯定无法访问,出现错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值