c++ virtual table

class Base {

public:
	Base(int a): a_(a) {}

	virtual void f() { cout << "Base::f" << endl; }

	virtual void g() { cout << "Base::g" << endl; }

	virtual void h() { cout << "Base::h" << endl; }
private:
	int a_;
};

int main() {
	// your code goes here
	typedef void(*Fun)(void);

	Base b(5);

	Fun pFun = NULL;
	
	cout << "a_:" << *((int*)&b + 2) << endl;

	cout << "虚函数表地址:" << (int*)(&b) << endl;

	int* vtable = (int*)*(int*)(&b);
	cout << "虚函数表 — 第一个函数地址:" << vtable << endl;

	// Invoke the first virtual function

	//pFun = (Fun)*((int*)*(int*)(&b));
	pFun = (Fun)*(vtable);
	pFun();
	pFun = (Fun)*((int*)*(int*)(&b) + 2);
	pFun();
	pFun = (Fun)*(vtable + 4);
	pFun();
        cout << "vtable end: " << (Fun)*(vtable + 6) << std::endl;

       // vtable and end of vtable
       int** pVtab = (int**)&b;
       pFun = (Fun)pVtab[0][0];
       pFun();  // base::f
       pFun = (Fun)pVtab[0][1];
       cout << pFun << endl;
       pFun = (Fun)pVtab[0][2];
       pFun();  // base::g
       pFun = (Fun)pVtab[0][3];
       cout << pFun << endl;
       pFun = (Fun)pVtab[0][4];
       pFun();  // base::h
       pFun = (Fun)pVtab[0][5];
       cout << pFun << endl;
       pFun = (Fun)pVtab[0][6];
       cout << pFun << endl;
       pFun = (Fun)pVtab[0][7];
       cout << pFun << endl;


	return 0;
}
输出结果:

a_:5
虚函数表地址:0x7ffe3f0a5970
虚函数表 ? 第一个函数地址:0x400e70
Base::f
Base::g
Base::h
vtable end: 1
Base::f
0
Base::g
0
Base::h
0
1
1

类static_cast、dynamic_cast与RTTI

1、static_cast

class Base {
    public:
        virtual void f() {
            cout << "Base::f() " << endl;
        }

};

class Derive: public Base {
    public:
        virtual void f() {
            cout << "Derive::f() " << endl;
        }

        virtual void f2() {
            cout << "Derive::f2() " << endl;
        }
};

int main(){
    // static_cast
    Base *pb1 = new Derive();
    Derive *pd1 = static_cast<Derive*>(pb1);
    pd1 -> f();

    Base *pb2 = new Base();
    Derive *pd2 = static_cast<Derive*>(pb2);
    pd2 -> f();
    //pd2 -> f2();  // core, base no f2()

    delete pb1;
    delete pb2;
    return 0;
}

static_cast可以在基类和派生类之间转换(偏移指针),编译时确定,不保证类型转换安全。

2、dynamic_cast

class Base {
    public:
        virtual void f() {
            cout << "Base::f() " << endl;
        }

};

class Derive: public Base {
    public:
        virtual void f() {
            cout << "Derive::f() " << endl;
        }

        virtual void f2() {
            cout << "Derive::f2() " << endl;
        }
};

int main(){
// dynamic_cast
    Base *pb3 = new Derive();
    Derive *pd3 = dynamic_cast<Derive*>(pb3);   // down cast
    pd3 -> f();

    Base *pb4 = new Base();
    Derive *pd4 = dynamic_cast<Derive*>(pb4);   // up cast 
    if(pd4){                    // pd4 is NULL here
        pd4 -> f();
        pd4 -> f2(); 
    }

    delete pb3;
    delete pb4;

    return 0;
}

专门用于用于有继承关系类之间转换,尤其是向下转换,运行时确定,是类型安全的。

3、RTTI