《深入探索C++对象模型》第一章:关于对象

26 篇文章 1 订阅

1、封装后的成本会增加吗?

对于一个普通的class,即不含虚函数,没有继承virtual base class(虽然通常不含有虚函数说明不存在继承体系),封装后,并没有增加成本,data members直接放在object内,就像在struct里的表现一样,而member functions虽然在class内声明,却不出现在object里(这个后面会说到,其实函数会被签名化,转换为nomember的形式调用)

所以C++在布局以及存取时间上主要的额外负担是由virual引起的

(1)virtual fucntion机制:用以支持一个有效率的执行期绑定(虚函数表)

(2)virtual base class:用以实现多次出现在继承体系中的base class,有一个单一而被共享的实例(虚表会被扩充,加入偏移量)

另外还有一些多重继承下的额外负担,发生在一个derived和其第二或者候机之间base class的转换之间(这里同样需要对pointer or reference进行偏移操作)

2、C++对象模型

前面几种就不赘述了,主要来探讨一下虚函数表模型:

Nonstatic data members被配置于每个class object内,static data members则被放在class object之外,static和nonstatic function members放在class object之外,关于virtual则以下面两个步骤支持:

(1)每个class产生出一堆指向virtual functions 的指针,放在表格中,此表格称为virtual table(vtbl)

(2)每个class object被安插一个指针,指向相关的virtual table(vtbl),通常这个指针称为vptr。vptr的设定和重置由construct、destructor、和copy assignment运算符自动完成,每一个class所关联的type_info object也经由virtual table被指出来,通常放在表格的第一个slot。

这里解释一下type_info object是干什么用的,实际上是用来支持runtime type identification,即RTTI,那么这个RTTI又是用来干什么的呢?通过运行时类型信息程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。RTTI提供了以下两个非常有用的操作符:
(1)typeid操作符,返回指针和引用所指的实际类型。
(2)dynamic_cast操作符,将基类类型的指针或引用安全地转换为派生类型的指针或引用。

3、指针的类型

我们来探讨一下一个简单的问题,一个指向int的指针和指向char的指针有什么区别呢?从内存的需求来看,其实没什么不同,都是一个word大小。其实指针的类型会教导编译器如何解释某个特定地址中的内存内容及其大小,即对这段内存里的内容的解释方式。比如int *p,编译器会知道内容为int,而且边界大小为4个字节。话有说回来,对于void*类型的指针咋办呢?很遗憾,编译器不知道怎么处理。一个指针的类型将在编译期间决定以下两点:

(1)固定的可用接口,也就是说某个类型的指针只能有该类型应有的操作

(2)该接口的access level,对于class来说

对于以下代码,我们来考虑两个问题:

/*
ZooAnimal是基类,rotate虚函数,Bear是派生类
*/
Bear b;
ZooAnimal za = b;
za.rotate();
(1)为什么rotate()所调用的是ZooAnimal实例而不是Bear实例呢?

(2)如果初始化函数将一个object内容完整拷贝到另一个object区,为什么za的vptr不指向Bear的virtual table?

对于第一个问题,利用对象显示调用,是不会发生多态的,并没有通过虚表进行索引,而是在编译期间直接编码(即成员函数会被修改签名,直接转换为nomember形式调用)

对于第二个问题,拷贝构造的时候,编译器合成的构造函数并不会对vptr进行覆盖,除非自己定义一个重载版本拷贝构造函数,对其进行覆盖


第一章的知识点就说到这里...省略了一些自己感觉不是很难懂的东西,吃饭去...,下午继续更新后续章节,秋招,fighting!!!


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值