深度探索C++对象模型笔记(一)

本文探讨了C++中封装特性的实现方式及其对程序的影响,对比了C++与C在封装上的区别,并深入介绍了虚函数支持运行时绑定机制的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

封装的开销开销
C++较C多了一些封装的特性,增加封装特性不会引起布局(layout)的开销,C++类的成员数据直接包含在每个对象内部,而noninline成员函数虽然在类中申明,但不会欻现在每个对象内部,每个noninline的成员函数仅产生一个唯一的函数实体。而inline函数在会为每个对象生成一个函数实体。因此C++类的封装并未带来任何空间或执行期间的不良,仅仅因为virtual的原因带来一些时间上的额外负担。
        虚函数支持运行时邦定机制
      在一个多重继承的结构中,虚基类支持单个共享的实例
如:
class CBase{};
class CSub1 : virtual public CBase{};
class CSub2 : virtual public CBase{};
class CSub : public CSub1,public CSub2{};
在CSub类的一个实例中仅包含一个CBase的实例

对象模型
C++中,共有两类数据成员static、nonstatic,三类成员函数:static、nonstatic、virtual

简单对象模型
这种模型的主要目的是降低编译器在编译过程中空间占用和生成的最终程序运行效率上的复杂性。在这种模型中,每个对象是一个时隙序列,每个时隙指向一个成员。对象的成员按照成员在类的声明中的顺序分配时隙,每个数据成员和函数成员都分配到一个时隙。
在此模型中,对象的每个成员没有分配到对象内部,对象内部仅仅存放一个成员变量的地址。这样可以避免因为不同的数据类型需要不同大小的存储空间。在对象内部的成员按照时隙的索引来表识
在现实中,这种对象模型没有使用,但其中索引和时隙编号的概念延伸到了C++ 指向成员(pointer-to-member)的概念

表驱动模型

所有的数据成员和成员函数各存放到表中,对象的实例包含指向这两个表的指针。成员函数表是时隙序列,每个时隙代表一个成员函数。数据成员表直接存放数据成员

这种模型也没有使用到C++模型中,但成员函数表支持了是高效运行时解析虚函数的传统实现

C++对象模型
nonstatic 数据成员直接在每个对象的内部存放,静态的数据成员、所有的成员函数存放到对象的外部,虚寒树通过如下方法来实现:
  每个类生成一张包含所有指向虚函数的所有指针的表(虚表)
  类的每个实例化对象包含一个指向虚表的指针(vptr),设置、删除和重置vptr都由构造函数、析构函数、拷贝构造函数来自动完成。和每个对象相关的用来支持运行时类型标识的type_info信息也存放在虚表中,通常是该表的第一个时隙。

对象差异
c++支持三种programming paradigm。
顺序模型,因为C++完全兼容C,而C支持顺序模型
ADT,抽象数据类型模型
面向对象模型

建议在程序内部仅适用一种programming paradigm,否则会引起一系列比较复杂的问题:具体问题参见

个人的理解:ADT模型是一种基于对象的机制如:VB6.0是基于对象的模型,他提供了对象,对象内部可以封装方法、属性等内容,但他没有提供面向对象的继承和多态,仅仅提供了封装机制。而面向象的模型提供了所有的封装、继承、多态机制。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值