1 关于对象(深入探索C++对象模型)

C++在加入封装后(只含有数据成员和普通成员函数)的布局成本增加了多少?

答案是并没有增加布局成本。就像C struct一样,memeber functions虽然含在class的声明之内,却不出现在object中。每一个non-inline member function只会诞生一个函数实体。至于每一个“拥有零个或一个定义的” inline function则会在其每一个使用者(模块)身上产生一个函数实体。

C++在布局以及存取时间上主要的额外负担是由virtual引起的包括:

  • virtual funciton机制,用以支持一个有效率的“执行期绑定”(runtime binding)
  • virtual base class,用以实现“多次出现在继承体系中的base class,有一个单一而被共享的实体”

1.1 C++对象模型

在C++中,有两种class data members:static 和 nonstatic,以及三种class member functions:static、nonstatic和virtual。在C++对象模型中:

  • nonstatic data members被配置于每一个class object之内
  • static data members则被存放在所有的class object之外(全局静态区)
  • static被放在所有的class object之外
  • nonstatic function members也被放在所有的class object之外
  • virtual需要两个步骤来完成。

virtual的两个步骤支持

  1.  每个class产生出一堆指向virtual functions的指针,放在表格之中。这个表格被称为virtual table(vtbl)
  2. 每一个class object被安插一个指针,指向相关的virtual table。通常这个指针被称为vptr。vptr的设定和重置都由每一个class的constructor、destructor和copy assignment运算符自动完成。每一个class所关联的type_info object(用以支持runtime type identification, RTTI)也经由virtual table被指出来,通常放在表格的第一个slot处

                                                          

上图说明了C++对象模型如何应用于Point Class身上,这个模型的主要优点在于它的空间和存取时间的效率。主要缺点是:如果应用程序代码未曾改变,但所用到的class objects的nonstatic data members有所修改(有可能是增加、移除或更改),那么应用程序代码同样得重新编译。

继承关系可以指定为虚拟(virtual,也就是共享的意思):在虚拟继承的情况下,base class不管在继承链中被派生(derived)多少次,永远会存在一个实例(称为subobject)

1.2 1.3 对象的差异

C++以下列方法支持多态:

  • 经由一组隐式的转化操作。例如把一个derived class指针转化为一个指向其public base type的指针
  • 经由virtual function机制
  • 经由dynamic_casttypeid运算符

多态的主要用途是经由一个共同的接口来影响类型的封装,这个接口通常被定义在一个抽象的base class中。这个共享接口是以virtual function机制引发的,它可以在执行期根据object的真正类型解析出到底是哪一个函数实体被调用

需要多少内存才能表现一个class object?

  • nonstatic data members的总和大小
  • 加上任何由于aliginment的需求而填补上去的空间(可能存在于members之间,也可能存在于集合体边界)
  • 加上为了支持virtual而由内部产生的任何额外负担

一个指针(引用),不管它指向哪一种数据结构,指针本身所需的内存大小是固定的。“指向不同类型的各指针”间的差异表现在其所寻址出来的object类型不同。“指针类型”会教导编译器如何解释某个特定地址中的内存内容及其大小

转型(cast)其实是一种编译器指令。大部分情况下它并不改变一个指针所含的真正地址,它只影响“被指出之内存的大小和其内容”的解释方式

当一个base class object被直接初始化为(或被指定为)一个derived class object时,derived object就会被切割(sliced)以塞入较小的base type内存中,derived type将没有留下任何蛛丝马迹。多态于是不再呈现,而一个严格的编译器可以在编译器解析一个“通过此object而触发的virtual function调用操作”,因而回避virtual机制(提高效率)。如果virtual function被定义为inline,则更有效率上的大收获。

C++通过Class的pointer和reference来支持多态,这种程序设计风格就被称为“面向对象”(OO)

C++也支持ADT程序风格,被称为OB。如string class就是一种非多态的数据类型。这种风格速度更快(函数调用在编译期解析完成)、空间紧凑(不需要用于支持virtual的额外负担),但实际发缺乏弹性

参考博客:https://www.cnblogs.com/lengender-12/p/6944042.html

参考书籍:《深入探索C++对象模型》侯捷

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值