为什么通过空指针(NULL)可以正确调用类的部分成员函数

本文探讨了为何通过空指针(NULL)可以调用C++类的部分成员函数。关键在于静态成员函数不依赖this指针,而非静态成员函数即使在this为空的情况下,只要不涉及成员变量也可以执行。但一旦涉及到this指针访问成员变量,程序将崩溃。通过对汇编代码的分析,揭示了this指针在成员函数调用中的传递和使用方式。
摘要由CSDN通过智能技术生成
#include <iostream>

using namespace std;

class B {
public:
    void foo() { cout << "B foo " << endl; }
    void pp() { cout << "B pp" << endl; }
    void FunctionB() { cout << "funB" << endl; }
};

int main()
{
    B *somenull = NULL;
    somenull->foo();
    somenull->pp();
    somenull->FunctionB();

    return 0;
}

为什么 somenull 为空指针,还能运行通过呢?

可以阐明“静态绑定”和“动态绑定”的区别。
真正的原因是:因为对于非虚成员函数,C++这门语言是静态绑定的。这也是C++语言和其它语言Java, Python的一个显著区别。以此下面的语句为例:
somenull->foo();
这语句的意图是:调用对象somenull的foo成员函数。如果这句话在Java或Python等动态绑定的语言之中,编译器生成的代码大概是:
找到somenull的foo成员函数,调用它。(注意,这里的找到是程序运行的时候才找的,这也是所谓动态绑定的含义:运行时才绑定这个函数名与其对应的实际代码。有些地方也称这种机制为迟绑定,晚绑定。)
但是对于C++。为了保证程序的运行时效率,C++的设计者认为凡是编译时能确定的事情,就不要拖到运行时再查找了。所以C++的编译器看到这句话会这么干:
1:查找somenull的类型,发现它有一个非虚的成员函数叫foo。(编译器干的)
2:找到了,在这里生成一个函数调用,直接调B::foo(somenull)。
所以到了运行时,由于foo()函数里面并没有任何需要解引用somenull指针的代码,所以真实情况下也不会引发segment fault。这里对成员函数的解析,和查找其对应的代码的工作都是在编译阶段完成而非运行时完成的,这就是所谓的静态绑定,也叫早绑定。

正确理解C++的静态绑定可以理解一些特殊情况下C++的行为。

this 指针是空指针 不去骚扰他 他就不搞死你
你敢动他试试

如果还没有看烦,可以参考下面的这些东西。

有下面的一个简单的类:

class  CNullPointCall
{
public :
    
static   void  Test1();
    
void  Test2();
    
void  Test3( int  iTest);
    
void  Test4();

private :
    
static   int  m_iStatic;
    
int  m_iTest;
};

int  CNullPointCall::m_iStatic  =   0 ;

void  CNullPointCall::Test1()
{
    cout 
<<  m_iStatic  <<  endl;
}

void  CNullPointCall::Test2()
{
    cout 
<<   " Very Cool! "   <<  endl; 
}

void  CNullPointCall::Test3(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值