代码改变世界

从实例分析成员函数的调用机制

2016-08-28 10:49  shuaihanhungry  阅读(272)  评论(0编辑  收藏  举报

第1个测试如果不好理解可以把转换过程中的各个指针打印出来。配上注释已经很好理解了。

#include <bits/stdc++.h>
using namespace std;

class A {
public:
    virtual void a() {
        cout << "a" << endl;
    }
};

class B {
public:
    virtual void b() {
        cout << "b" << endl;
    }
};

class C: public A, public B {
public:
    virtual void c() {
        cout << "c" << endl;
    }
};

class D {
public:
    int m;
    void d() {
        cout << "d" << endl;
    }
};

int main() {
    /*
    * 虚函数的调用不会用到虚函数名,不同于静态成员函数和非静态成员函数
    * 编译器会在内部对虚函数的调用转换为 (* ptr->vptr[1])(ptr) 这样的形式
    * 其中 ptr 表示 this 指针,vptr 指向 virtual table ,1 为 virtual table slot 的索引值
    */
    C *pc = new C;
    reinterpret_cast<A *>((B*) pc)->a(); //b

    /*
    * 编译器内部会将非静态成员函数转换为对等的非成员函数,该转换经历 3 个步骤
    * 1)改写函数签名,添加额外参数 this
    * 2)将对数据成员的存取改为由 this 指针来存取
    * 3)重新写成一个外部函数
    */
    D *pd = 0;
    pd->d(); //d

    return 0;
}