C++中使用空对象指针调用成员函数

引入问题

先看下面这段代码:

#include <cstdlib>
#include <iostream>

class A {
public:
    void f() {
        if (this == nullptr) {
            std::cout << "is null" << std::endl;
        }
        else {
            std::cout << "not null" << std::endl;
        }
    }
};

int main()
{
    A* p = new A();
    p->f();
    delete p;
    p = nullptr;

    //我本以为程序执行到这一句会奔溃,结果没有
    p->f();

    system("pause");
    return 0;
}

执行结果:

not null
is null
请按任意键继续. . .

我第一个疑惑的点是,为啥空指针还能调用成员函数。

修改代码,验证猜想

#include <cstdlib>
#include <iostream>

class A {
public:
    A::A() {
        m_num = 666;
    }

    //成员函数1,没有访问成员变量
    void member_func_1() {
        if (this == nullptr) {
            std::cout << "is null" << std::endl;
        }
        else {
            std::cout << "not null" << std::endl;
        }
    }

    //成员函数2,有访问成员变量
    void member_func_2() {
        if (this == nullptr) {
            std::cout << "is null ";
            std::cout << m_num << std::endl;
        }
        else {
            std::cout << "not null ";
            std::cout << m_num << std::endl;
        }
    }

    //静态成员函数,没有this
    static void s_memeber_func() {
        std::cout << "static member func called" << std::endl;
    }

    //虚函数
    virtual void v_member_func() {
        std::cout << "virtual member func called" << std::endl;
    }
private:
    int m_num;
};

int main()
{
    A* p = new A();
    p->member_func_1();
    p->member_func_2();
    p->s_memeber_func();
    p->v_member_func();
    delete p;
    p = nullptr;

    p->member_func_1();//ok
    p->member_func_2();//error
    p->s_memeber_func();//ok
    p->v_member_func();//error

    system("pause");
    return 0;
}

类的成员函数并不与具体对象绑定,所有的对象共用同一份成员函数体,当程序被编译后,成员函数的地址即已确定,这份共有的成员函数体之所以能够把不同对象的数据区分开来,靠的是隐式传递给成员函数的this指针,成员函数中对成员变量的访问都是转化成”this->数据成员”的方式。

为何会有这篇文

因为我看到了这样一句代码 if (this == nullptr)return;