C++ 类 内存分布 虚函数 单继承 多继承

C++ 类 内存分布 虚函数 单继承 多继承
重点内容
一、首先看看没有继承情况下类的内存分布:
1.1 定义一个简单的类,没有虚函数。
代码如下:

#include<iostream>
using namespace std;
class Base
{
public:
    int Base_1;
    int Base_2;
public:
    void func1();
};
int main(){
    Base obj_base;
    return 0;
}

编译,得到的内存分布图如下所示:
内存分布图
从这里可以看到普通类的内存排布方式,成员变量依据声明的顺序进行排列,类内偏移从0开始,普通成员函数不占内存空间。这里没有考虑char等成员变量的字节对齐方式等问题。
1.2 定义一个简单的类,包含虚函数。
#include<iostream>
using namespace std;
class Base
{
public:
int Base_1;
int Base_2;
public:
void func1();
virtual void func2(){};
virtual void func3(){};
};
int main(){
Base obj_base;
return 0;
}

编译,得到的内存分布图如下所示:
[
从图中可以看出,这个内存结构图分成了两个部分,上面是类的内存分布,下面是虚函数表。这里的编译环境VS2013。从结果可知,编译器是将虚表指针{vfptr}放在类内存的开始处,从图可知其偏移量为0,接着放置类其他成员变量,从图可知,Base_1和Base_2的偏移量分别为4,8。下面部分是类的虚函数表。在&Base_meta后面的0表示,这张虚函数表对应的虚指针{vfptr}在类内存中的分布。接着下面列出类的虚函数,虚函数左边表示虚函数的号。

1.3 单一非虚继承。

#include<iostream>
using namespace std;
class Base
{
public:
    int Base_1;
    int Base_2;
public:
    void func1();
    virtual void func2(){};
    virtual void func3(){};
};
class D :public Base{
public:
    int d_1;
public:
    virtual void func2(){};
};
int main()
{
    return 0;
}

运行结果:
这里写图片描述

分析:
派生类继承了基类的全部,包括虚表指针{vfptr}和其他变量。同时将继承父类的东西放在类内存的开始处,这样,{vfptr}的地址偏移为0,同时派生类也维护一个自己的虚函数表。总结:在非虚继承下:
(1) 派生类会继承基类的全部,包括虚基指针。
(2) 派生类和基类会各自维护一个虚函数表,他们不相同,不是同一张表。从以上结果体现为,基类虚表为Base::$vftable,派生类的虚表为D::vftable。但是他们虚表对应的虚指针是一样的。

1.4 单一虚继承。
代码:

#include<iostream>
using namespace std;
class Base
{
public:
    int Base_1;
    int Base_2;
public:
    void func1();
    virtual void func2(){};
    virtual void func3(){};
};
class D :virtual public Base{
public:
    int d_1;
public:
    virtual void func2(){};
};
int main()
{
    return 0;
}

运行结果:
这里写图片描述

派生类继承了基类的全部,包括虚表指针{vfptr}和其他变量。但是不是将继承父类的东西放在类内存的开始处。在类内存中开始出放置的是自己的虚指针{vbptr},接着自己的成员变量,最后再放置从基类派生下来的数据。此时,派生类有了2个虚指针,一个是自己的虚指针,另一个是从基类派生下来的虚基指针,对应就有2张虚表。各个虚表下面的数字就表示其在类内存中的偏移量。总结:在虚继承下:
(1) 派生类会继承基类的全部,包括虚基指针。但是不是将其放在类内存的地址偏移0处。派生类会新生成虚指针,放在类内存地址偏移量为0处。
(2) 派生类有2个虚指针,对应有两张虚函数表。

特别感谢:
http://www.cnblogs.com/jerry19880126/p/3616999.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值