码迷,mamicode.com
首页 > 编程语言 > 详细

c++继承和多态

时间:2016-05-07 10:15:18      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:

c++继承和多态:

1.普通继承派生类对象的内存布局

 class Base
 {
 public:
     void show() const
     {
         cout << "Base::show()" << endl;
     }
 protected:
     int ma;
 };

class Derive: public Base
{
public:
    void show() const
    {
        cout << "Derive::show()" << endl;
    }
private:
    int mb;
};

在没有虚函数时,派生类对象内存分布如图
Derive::
    Base::
        ma
    mb
这两个show()函数的关系是隐藏
-------------------------------------------------------

若基类存在虚函数:两个show()函数是覆盖
class Base
 {
 public:
     virtual void show() const
     {
         cout << "Base::show()" << endl;
     }
 protected:
     int ma;
 };

class Derive: public Base
{
public:
    void show() const
    {
        cout << "Derive::show()" << endl;
    }
private:
    int mb;
};
此时派生类的内存布局:
Derive::
    Base::
        *vfptr
        ma
    mb
虚表指针指向一个虚表,虚表内容如下
Base::vftable
-2:  RIIT //运行的类型信息,它提供了运行时确定对象类型的方法。           使用内建的 RTTI 中的运算符:typeid 和 dynamic_cast确定对象的动态类型 
-1:  vfptr在内存布局的偏移量
0:  show 虚函数的入口地址

如果virtual加在派生类的show上,则派生类的内存布局
Derive::
    vfptr
    Base::
        ma
    mb
----------------------------------------------------------
编译器是在构造函数创建这个虚表指针以及虚表的。

那么编译器是如何利用虚表指针与虚表来实现多态的呢?是这样的,当创建一个含有虚函数的父类的对象时,编译器在对象构造时将虚表指针指向父类的虚函数;同样,当创建子类的对象时,编译器在构造函数里将虚表指针(子类只有一个虚表指针,它来自父类)指向子类的虚表(这个虚表里面的虚函数入口地址是子类的)。

所以,如果是调用Base *p = new Derived();生成的是子类的对象,在构造时,子类对象的虚指针指向的是子类的虚表,接着由Derived*到Base*的转换并没有改变虚表指针,所以这时候p->show,实际上是p->vfptr->show,它在构造的时候就已经指向了子类虚函数,所以调用的是子类的虚函数,这就是多态了。

2.虚继承下派生类的内存布局
///虚拟继承是为了解决多重继承下公共基类的多份拷贝问题.

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

class D11 : virtual public Base
{
public:
    int mb; 
};

class D12: virtual public Base
{
publilc:
    int mc;
};

class D21:public D11, public D12
{
    int md;
};

D21的对象内存布局
////////////////////////////////////////////////////////////////////////
D21::
    D11::
        vbptr
        mb
    D12::
        vbptr
        mb
md
    Base::
        vfptr
        ma
////////////////////////////////////////////////////////////////////////

其中虚基类指针vbptr指向vbtable

vbtable::
0 :      vbptr在他当前类的内存偏移量
1:    vbptr到虚基类数据的偏移量

c++继承和多态

标签:

原文地址:http://blog.csdn.net/it_lover_/article/details/51334552

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!