封装的开销开销
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是基于对象的模型,他提供了对象,对象内部可以封装方法、属性等内容,但他没有提供面向对象的继承和多态,仅仅提供了封装机制。而面向象的模型提供了所有的封装、继承、多态机制。