c++ 虚函数

来源:互联网 发布:淘宝dnf游戏币交易 编辑:程序博客网 时间:2024/06/11 06:18

虚函数

一个拥有虚函数的类内部会有一个成员变量vptr,一个四字节大小的指针,指向虚函数表,虚函数表中记录了该类的各个虚函数的入口地址,如果该类重载了继承的虚函数,那么就存放自己的虚函数地址,否则就是父类的虚函数地址

 

 ////代码如下:

class Base {public:virtual void f() { cout << "Base::f" << endl; }virtual void g() { cout << "Base::g" << endl; }virtual void h() { cout << "Base::h" << endl; }};typedef void(*Fun)(void);//函数指针int main(){Base b;Fun pFun1 = NULL;Fun pFun2 = NULL;Fun pFun3 = NULL;cout << "虚函数表地址:" << (int*)(&b) << endl;cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;// Invoke the first virtual function  pFun1 = (Fun)*((int*)*(int*)(&b));pFun2= (Fun)*((int*)*(int*)(&b)+1);  // Base::g()pFun3= (Fun)*((int*)*(int*)(&b)+2);  // Base::h()pFun1();pFun2();pFun3();return 0;}

结果:

结构图如下:

 

 

一般继承(无虚函数覆盖)

来看看继承时的虚函数表是什么样的。假设有如下所示的一个继承关系:

 

 

请注意,在这个继承关系中,子类没有重载任何父类的函数。那么,在派生类的实例中,其虚函数表如下所示:

 

对于实例:Derive d;的虚函数表如下:

 

我们可以看到下面几点:

1)虚函数按照其声明顺序放于表中。

2)父类的虚函数在子类的虚函数前面

代码:

class Base {public:virtual void f() { cout << "Base::f" << endl; }virtual void g() { cout << "Base::g" << endl; }virtual void h() { cout << "Base::h" << endl; }};class Derive:public Base{public:virtual void f1() { cout << "Base::f1" << endl; }virtual void g1() { cout << "Base::g1" << endl; }virtual void h1() { cout << "Base::h1" << endl; }};typedef void(*Fun)(void);//函数指针int main(){Derive b;Fun pFun1 = NULL,pFun2 = NULL,pFun3 = NULL,pFun4 = NULL,pFun5 = NULL,pFun6 = NULL;;cout << "虚函数表地址:" << (int*)(&b) << endl;cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;// Invoke the first virtual function  pFun1 = (Fun)*((int*)*(int*)(&b));pFun2= (Fun)*((int*)*(int*)(&b)+1);  // Base::g()pFun3= (Fun)*((int*)*(int*)(&b)+2);  // Base::h()pFun4= (Fun)*((int*)*(int*)(&b)+3);  // Base::h()pFun5= (Fun)*((int*)*(int*)(&b)+4);  // Base::h()pFun6= (Fun)*((int*)*(int*)(&b)+5);  // Base::h()pFun1();pFun2();pFun3();pFun4();pFun5();pFun6();return 0;}


结果:

 

一般继承(有虚函数覆盖)

 

覆盖父类的虚函数是很显然的事情,不然,虚函数就变得毫无意义。下面,我们来看一下,如果子类中有虚函数重载了父类的虚函数,会是一个什么样子?假设,我们有下面这样的一个继承关系。

 

 

 

为了让大家看到被继承过后的效果,在这个类的设计中,我只覆盖了父类的一个函数:f()。那么,对于派生类的实例,其虚函数表会是下面的一个样子:

 

 

我们从表中可以看到下面几点,

1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置

2)没有被覆盖的函数依旧

代码:

待续......

 

 

 

 参考:文字描述参考 谢谢  陈皓专栏(技 术) (RSS)   http://blog.csdn.net/haoel/article/details/1948051/

自己备录,
原创粉丝点击