c++对象模型01:三种常见对象模型

对象模型

在C++中,有两种数据成员(class data members):static成员 和nonstatic成员,以及三种类成员函数(class member functions):static、nonstatic和virtual:

在这里插入图片描述

接下来我们看三种对象模型是如何存放成员变量的

简单对象模型

在该模型下,对象由一系列的指针组成,每一个指针都指向一个数据成员或成员函数,顺序按声明顺序排列,也就是说,每个数据成员和成员函数在类中所占的大小是相同的,都为一个指针的大小。

在这里插入图片描述

表格驱动对象模型

把成员函数放在一个成员函数表中,每个slot指向一个成员函数,slot中存放的是成员函数指针;把数据成员放在一个数据成员表中,存放数据本身。成员对象包含两个指针分别指向前面这两个表格。

C++对象模型

在此模型下,nonstatic 数据成员被置于每一个类对象中,而static数据成员被置于类对象之外。static与nonstatic函数也都放在类对象之外,而对于virtual 函数,则通过虚函数表+虚指针来支持,具体如下:

  • 每个类生成一个表格,称为虚表(virtual table,简称vtbl)。虚表中存放着一堆指针,这些指针指向该类每一个虚函数。虚表中的函数地址将按声明时的顺序排列,不过当子类有多个重载函数时例外。
  • 每个类对象都拥有一个虚表指针(vptr),指向相关的虚函数表vtbl,由编译器为其生成。虚表指针的设定与重置皆由类的复制控制(也即是构造函数、析构函数、赋值操作符)来完成。vptr的位置为编译器决定,传统上它被放在所有显示声明的成员之后,不过现在许多编译器把vptr放在一个类对象的最前端。
  • 虚函数表的前面设置了一个指向type_info的指针,用以支持RTTI(Run Time Type Identification,运行时类型识别)。RTTI是为多态而生成的信息,包括对象继承关系,对象本身的描述等,只有具有虚函数的对象在会生成。

这个模型的优点在于它的空间和存取时间的效率;缺点如下:如果应用程序本身未改变,但当所使用的类的non static数据成员添加删除或修改时,需要重新编译。

在这里插入图片描述
在这里插入图片描述

对象b含有一个__vfptr,即vprt。并且只有nonstatic数据成员被放置于对象内。vfptr中有两个指针类型的数据(地址),第一个指向了Base类的析构函数,第二个指向了Base的虚函数print,顺序与声明顺序相同。

代码演示
void testBase(Base& p)
{
    cout << "对象的内存起始地址:" << &p << endl;
    cout << "虚函数表地址:" << (int*)(&p) << endl;
    //验证虚表
    cout << "虚函数表第一个函数的地址:" << (int*)*((int*)(&p)) << endl;
    cout << "析构函数的地址:" << (int*)*(int*)*((int*)(&p)) << endl;
    cout << "虚函数表中,第二个虚函数即print()的地址:" << ((int*)*(int*)(&p) + 1) << endl;
    //通过地址调用虚函数print()
    typedef void(*Fun)(void);
    Fun IsPrint = (Fun) * ((int*)*(int*)(&p) + 1);
    cout << endl;
    cout << "调用了虚函数";
    IsPrint(); //若地址正确,则调用了Base类的虚函数print()
    cout << endl;
    //输入static函数的地址
    p.countI();//先调用函数以产生一个实例
    cout << "static函数countI()的地址:" << p.countI << endl;
    //验证nonstatic数据成员
    cout << "推测nonstatic数据成员baseI的地址:" << (int*)(&p) + 1 << endl;
    cout << "根据推测出的地址,输出该地址的值:" << *((int*)(&p) + 1) << endl;
    cout << "Base::getI():" << p.getI() << endl;
}
int main() {
	Base b(1000);
    testBase(b);
    cout << endl;
}

在这里插入图片描述

结果分析

虚函数表的第一个位置是析构函数,第二个位置是虚函数print函数,可以通过地址而不是对象调用它。

虚表指针的下一个位置是非静态成员变量,静态成员函数的地址段与虚表指针和非静态成员的地址段不同。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: COM(Component Object Model)是微软公司开发的一种面向对象的组件对象模型。它是一种可用于编写和调用应用程序的平台和语言无关的技术,具有广泛的应用。COM可以使不同的软件组件相互通信和交互,实现代码的复用和模块化开发。COM技术内幕-微软组件对象模型 PDF是一本关于COM技术的书籍,通过介绍COM技术的原理、架构和编程接口,帮助读者深入理解COM技术的内部工作原理和应用方法。 COM技术内幕-微软组件对象模型 PDF可以帮助读者了解COM的基本概念和核心概念,如COM对象、接口、类工厂等。它还介绍了COM对象的生命周期和内存管理,以及如何使用COM接口进行对象之间的通信和交互。此外,该书还讲解了COM的线程模型、注册表、组件的版本管理和卸载等相关内容。 通过阅读COM技术内幕-微软组件对象模型 PDF,读者可以深入了解COM技术的实现细节和应用技巧,掌握COM的高级编程技巧,提高软件开发和设计的效率。这本书适合有一定编程基础的读者阅读,特别是那些对COM技术感兴趣并希望进一步学习和应用的人员。 总之,COM技术内幕-微软组件对象模型 PDF是一本关于COM技术的详细指南和参考书,它可以帮助读者深入理解COM技术的内部工作原理和应用方法,提高软件开发和设计的技能水平。 ### 回答2: COM技术内幕-微软组件对象模型(Component Object Model,简称COM)是一种面向对象的软件组件模型,由微软公司开发,用于实现软件组件的互操作性。它在Windows操作系统中被广泛应用,为开发人员提供了一种在不同平台和编程语言之间交互的标准接口。 COM技术内幕-微软组件对象模型的PDF是一本介绍COM技术的相关文档。它详细讲解了COM的原理、架构、编程模型和相关的API,介绍了COM组件的开发、注册和部署等方面的知识。 这本PDF不仅适合初学者学习COM技术,也适合有一定基础的开发人员进一步深入了解COM的内部实现和高级特性。它可以帮助开发人员理解COM组件的生命周期、接口的多态性、对象模型的设计原则等重要概念。 此外,这本PDF还介绍了COM组件与.NET和Java等现代开发平台之间的互操作性。它解释了如何在COM组件和这些平台之间进行数据交换、方法调用等操作,为开发人员提供了实现跨平台开发的方法和技巧。 总之,COM技术内幕-微软组件对象模型的PDF对于想要深入理解和应用COM技术的开发人员来说是一本很有价值的参考资料。通过学习这本PDF,开发人员可以更加高效地开发和管理COM组件,提高软件的可复用性和扩展性。 ### 回答3: COM(Component Object Model)是微软公司开发的一种软件组件技术,用于实现软件的组件化开发和复用。COM技术内幕-微软组件对象模型(COM Internals - Microsoft Component Object Model)是一本介绍COM技术的PDF文件。 该PDF文件主要讲解了COM的原理、架构和用法。首先,它介绍了COM的产生背景和发展历程,让读者了解COM的起源和重要性。然后,它详细解释了COM的基本原理和核心概念,如COM对象、接口、类工厂等,帮助读者理解COM组件的结构和运作方式。 接着,该文件介绍了COM的编程模型,即如何使用COM来开发软件。它详细解释了COM的接口定义语言(IDL)和对象创建的过程,以及如何在不同编程语言(如C++、C#等)中使用COM进行开发。 此外,该PDF文件还讨论了COM的生命周期管理、线程安全性和版本控制等重要概念。它指导开发者如何正确地创建、使用和释放COM对象,并提供了一些常见问题的解决方法。 最后,该文件还介绍了COM的扩展技术和相关标准,如COM+、DCOM和COM浏览器等。它展示了COM在分布式系统、Web服务和企业应用中的应用场景,帮助读者拓展对COM技术的应用范围。 总之,COM技术内幕-微软组件对象模型是一本全面介绍COM技术的PDF文件,适合想要深入了解并应用COM技术的开发者和技术爱好者阅读。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值