#include <iostream> using namespace std; class Top { public: virtual void x(){cout << "top x" << endl;} virtual void print0(){cout << "top print" << endl;} public: int a; }; class Left:virtual public Top { public: virtual void x(){cout << "left x" << endl;} virtual void print1(){cout << "left print" << endl;} public: int b; }; int main() { /*first part*/ cout << sizeof(Top) << "\t" << sizeof(Left) << endl;//輸出:8 16 Left *left = new Left(); cout << left << " " << &left->b << " " << &left->a << endl; //輸出:0x8517008 0x851700c 0x8517014 /*second part*/ typedef void (*Func)(void); Func pFunc; pFunc = (Func)*((int *)*(int *)(left)); pFunc();//輸出:left x pFunc = (Func)*((int *)*(int *)(left)+1); pFunc();//輸出:left print // pFunc = (Func)*((int *)*(int *)(left)+2); // pFunc();//段錯誤 /*third part*/ pFunc = (Func)*((int *)*((int *)(left)+2)); pFunc();//輸出:left x pFunc = (Func)*((int *)*((int *)(left)+2)+1); pFunc();//輸出:top print // pFunc = (Func)*((int *)*((int *)(left)+2)+2); // pFunc();//段錯誤 delete left; return 0; }
從輸出狀況咱們能夠得知如下信息: 在具備虛函數的單一虛擬繼承時,子類中會有多個虛指針以及多個虛函數表。咱們能夠用以下圖來表示對應的內存佈局:
#include <iostream> using namespace std; class Top { public: virtual void x(){cout << "top x" << endl;} virtual void print0(){cout << "top print" << endl;} public: int a; }; class Left:virtual public Top { public: virtual void y(){cout << "left y" << endl;} virtual void print1(){cout << "left print" << endl;} public: int b; }; class Right:virtual public Top { public: virtual void z(){cout << "right z" << endl;} virtual void print2(){cout << "right print" << endl;} public: int c; }; class Bottom : public Left, public Right { public: virtual void y(){cout << "bottom y" << endl;} virtual void z(){cout << "bottom z" << endl;} virtual void print3(){cout << "bottom print" << endl;} public: int d; }; int main() { /*first part*/ cout << sizeof(Top) << "\t" << sizeof(Left) << "\t" << sizeof(Right) << "\t" << sizeof(Bottom) << endl; //輸出:8 16 16 28 Bottom *b = new Bottom(); cout << b << " " << &b->b << " " << &b->c << " " << &b->d << " " << &b->a << endl; //輸出:0x9814008 0x981400c 0x9814014 0x9814018 0x9814020 /*second part*/ typedef void (*Func)(void); Func pFunc; pFunc = (Func)*((int *)*(int *)(b)); pFunc();//輸出:bottom y pFunc = (Func)*((int *)*(int *)(b)+1); pFunc();//輸出:left print pFunc = (Func)*((int *)*(int *)(b)+2); pFunc();//輸出:bottom z pFunc = (Func)*((int *)*(int *)(b)+3); pFunc();//輸出:bottom print // pFunc = (Func)*((int *)*(int *)(b)+4); // pFunc();//段錯誤 /*third part*/ pFunc = (Func)*((int *)*((int *)(b)+2)); pFunc();//輸出:bottom z pFunc = (Func)*((int *)*((int *)(b)+2)+1); pFunc();//輸出:right print // pFunc = (Func)*((int *)*((int *)(b)+2)+2); // pFunc();//段錯誤 /*fourth part*/ pFunc = (Func)*((int *)*((int *)(b)+5)); pFunc();//輸出:top x pFunc = (Func)*((int *)*((int *)(b)+5)+1); pFunc();//輸出:top print // pFunc = (Func)*((int *)*((int *)(b)+5)+2); // pFunc();//段錯誤 delete b; return 0; }