`
mmdev
  • 浏览: 12916373 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

C++虚函数与多态

 
阅读更多

一提起C++的多态,很自然就想起了函数重载和虚函数的实现。函数重载是在编译时实现的一种多态,而运行时的一种多态可以通过虚函数来实现。具体一点的例子就是通过基类指针指向其子类的实例,然后来调用实际子类的成员函数。既然说到虚函数,那么虚函数表必然要提一下;我想用例子来加深一下对这方面的认识:

#include<iostream>
using namespace std;
 
class Base
{
public:
         Base(){}
         virtual ~Base(){}
         int b_num;

         virtual void func1(){cout<<"func1: In base~"<<endl;}
         virtual void func2(){cout<<"func2: In base~"<<endl;}
};

class Derive: public Base
{
public:
         Derive(){}
         ~Derive(){}

         int d_num;
         void func1(){cout<<"func1: In derive~"<<endl;}
};

int main()
{
         cout<<sizeof(Base)<<"  "<<sizeof(Derive)<<endl; 

         Derive d;
         Base* b=&d;
         b->func1();
         b->func2();

         return 0;
}


输出:

8 12

func1: In derive~

func2: In base~

对于类的内存组织的描述

(1)类Base的内存组织类似于:

VPTR是一个虚函数表指针,指向该类的虚函数表。由上图可以看出Base类的内存空间存放了该指针以及一个整型的数据成员,因此该类的长度为8.

(2)类Derive的内存组织类似于:

由上图可知,在派生类中VPTR指向了该类的一个虚函数表,这个是从基类的虚函数表中来的;由于派生类Derive中覆盖了基类的func1虚函数,那么新的虚函数表也做了相应的覆盖。

在派生类的内存空间中,存储了虚函数表指针VPTR,基类的数据成员b_num,还有自身的数据成员d_num,因此sizeof(Derive)的长度为12.

由于func1的函数在派生类中被覆盖,通过基类指针指向的派生类的虚函数表中的是Derive::func1();而func2()函数没有被覆盖,因此指向的还是派生类中虚表的Base::func2().

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics