本来是一道面试题目,想深究一下,加深自己对函数调用过程的理解,题目代码如下:

class A {
public:
    void f1() {
        cout << "f1 function" << endl;
    }
    void setA(int x) {
        a = x;
        cout << "setA() function" << endl;
    }
    int getA() {
        cout << "getA() function" << endl;
        return a; 
    }
    virtual f2() {
        cout << "f2 function" << endl;
    }
private:
    int a = 5;
};
A *a = nullptr;
a->f();
a->setA(10);
int t = getA();
a->f2();

依次调用上述的函数,结果如下图所示:

运行结果

首先,a是指向A类型的指针,它所指向的类型被编译器记住了,所以它可以调用A的成员函数。

但是,剩余几个的结果都是core dump,使用gdb分析产生的core文件,生成core文件的方法详细见如何使用GDB调试项目,可以看到产生core dump的语句都是使用到this指针的时候,但是this指针的值是0x0,所以会产生这种现象。

f1()、setA()和getA()都有一个隐藏的this参数,调试的时候能够使用step进入查看

step结果

非虚函数的地址在编译依然确定,但虚函数的地址需要查询虚函数表才能获知,而虚函数表的访问需要this指针,所以无法进入f2()函数内部。