浅谈C++对象的内存分布和虚函数表

发布时间 - 2026-01-10 22:05:27    点击率:

c++中一个类中无非有四种成员:静态数据成员和非静态数据成员,静态函数和非静态函数。

1、非静态数据成员被放在每一个对象体内作为对象专有的数据成员。

2、静态数据成员被提取出来放在程序的静态数据区内,为该类所有对象共享,因此只存在一份。

3、静态和非静态成员函数最终都被提取出来放在程序的代码段中并为该类所有对象共享,因此每一个成员函数也只能存在一份代码实体。在c++中类的成员函数都是保存在静态存储区中的 ,那静态函数也是保存在静态存储区中的,他们都是在类中保存同一个惫份。

因此,构成对象本身的只有数据,任何成员函数都不隶属于任何一个对象,非静态成员函数与对象的关系就是绑定,绑定的中介就是this指针。成员函数为该类所有对象共享,不仅是处于简化语言实现、节省存储的目的,而且是为了使同类对象有一致的行为。同类对象的行为虽然一致,但是操作不同的数据成员。

#include"iostream.h"
class A
{


private:
 int x;
 int y;


public:
 void sety()
 {
 y=5;
 }
 void print()
 {
 cout<<"x="<<x<<endl<<"y="<<y<<endl;
 }
};

void main()
{
 A a;
 a.sety();
 a.print();
 int *p=(int *)&a;//对象a的内存模型里面,只有非静态数据成员,所以是合理的。
 *p=6;
 a.print();
}

4、单继承的对象的内存布局,第一个为虚函数表指针vtbl,其后为成员且先基类后子类,虚函数表里包含了所有的虚函数的地址,以NULL结束。虚函数如果子类有重写,就由子类的重新的代替。

 <一> 上述类图的解释:B的v2覆盖了A的v2,C的v1覆盖了A的v1,C的v3覆盖了B的v3.

注意:发生覆盖的特征有:

1) 不同的范围(分别位于派生类与基类);

2) 函数名字相同;

3) 参数相同;

4) 基类函数必须有virtual关键字。

成员函数被重载的特征
 
(1)相同的范围(在同一个类中);
 
(2)函数名字相同;
 
(3)参数不同;
 
(4)virtual 关键字可有可无。

 
“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下
 
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
 
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)  

<二> 类C的对象的内存模型为:

单继承的对象的布局,第一个为虚函数表指针vtbl,其后为成员且先基类后子类,虚函数表里包含了所有的虚函数的地址,以NULL结束。虚函数如果子类有重写,就由子类的重新的代替。

5、与单继承相同的是所有的虚函数都包含在虚函数表中,所不同的多重继承有多个虚函数表,当子类对父类的虚函数有重写时,子类的函数替换父类的函数在对应的虚函数位置,当子类有新的虚函数时,这些虚函数被加在第一个虚函数表的后面。

<一> 对类图的解释:D的v3覆盖了B3的v3,另外D有一个新的虚函数vD。

<二> class D 的内存模型

总结:与单继承相同的是所有的虚函数都包含在虚函数表中,所不同的多重继承有多个虚函数表,当子类对父类的虚函数有重写时,子类的函数覆盖父类的函数在对应的虚函数位置,当子类有新的虚函数时,这些虚函数被加在第一个虚函数表的后面

6. 虚继承,使公共的基类在子类中只有一份,我们看到虚继承在多重继承的基础上多了vbtable来存储到公共基类的偏移。

<一>类图的解释:D2覆盖了B的vB,GD覆盖了D1的vD1同时也覆盖B的vB,GD也有自己的虚函数vGD。

<二> class GD的内存模型

总结:虚继承,使公共的基类在子类中只有一份,我们看到虚继承在多重继承的基础上多了vbtable来存储到公共基类的偏移

以上就是小编为大家带来的浅谈C++对象的内存分布和虚函数表全部内容了,希望大家多多支持~


# 虚函数表  # 内存  # C++虚函数表与类的内存分布深入分析理解  # C++内存分布及用法  # 解析C++类内存分布  # C++ 类中有虚函数(虚函数表)时 内存分布详解  # C++对象内存分布详解(包括字节对齐和虚函数表)  # C++浅析程序中内存的分布  # 子类  # 第一个  # 重写  # 类中  # 放在  # 的是  # 派生类  # 多个  # 绑定  # 就由  # 加在  # 区中  # 后为  # 上多  # 自己的  # 都是  # 有一  # 是在  # 也有  # 都不 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化  javascript中数组(Array)对象和字符串(String)对象的常用方法总结  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  html5如何实现懒加载图片_ intersectionobserver api用法【教程】  Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】  Laravel如何使用Eloquent进行子查询  魔方云NAT建站如何实现端口转发?  如何快速使用云服务器搭建个人网站?  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集  Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程  python中快速进行多个字符替换的方法小结  如何确保西部建站助手FTP传输的安全性?  HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】  大连网站制作公司哪家好一点,大连买房网站哪个好?  如何用VPS主机快速搭建个人网站?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  Laravel Octane如何提升性能_使用Laravel Octane加速你的应用  Laravel如何实现用户密码重置功能?(完整流程代码)  Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  如何正确选择百度移动适配建站域名?  为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  C#如何调用原生C++ COM对象详解  如何将凡科建站内容保存为本地文件?  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  如何在不使用负向后查找的情况下匹配特定条件前的换行符  高防服务器租用指南:配置选择与快速部署攻略  如何在阿里云虚拟主机上快速搭建个人网站?  LinuxCD持续部署教程_自动发布与回滚机制  Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件  Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康  香港服务器WordPress建站指南:SEO优化与高效部署策略  在线教育网站制作平台,山西立德教育官网?  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  如何快速查询网站的真实建站时间?  Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】  佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】  Laravel如何创建自定义Facades?(详细步骤)  独立制作一个网站多少钱,建立网站需要花多少钱?  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】  原生JS获取元素集合的子元素宽度实例  Laravel如何使用Telescope进行调试?(安装和使用教程)  EditPlus中的正则表达式实战(6)  如何在宝塔面板中修改默认建站目录?