深度探索C++对象模型要点

(1)如果类里面的成员变量只是内置类型的,那么类其实是不会合成构造函数的。在一下情况下才会合成构造函数

         1.当class内含一个成员变量,并且该成员变量有一个拷贝构造函数

         2.当class继承自一个基类,并且基类有一个拷贝构造函数

         3.当class声明一个或者多个虚函数的时候

         4.当class派生自一个继承串链,其中有一个或者多个虚基类。

(2)类Base和继承类Base的子类Derived,如果有这样的赋值, Base base = derived;将会导致类切割,如果derived类中有虚函数的话,也会将derived类中的vptr一同进行拷贝,如果是简简单单的bitwise拷贝的话,base和derived将指向同一个虚函数表,这会导致错误的。那么在拷贝的时候编译器会默认这个拷贝是深拷贝(调用的将是base的拷贝构造函数),会给base另外建立一个虚函数表,但是虚函数表里面的内容也是要改变的,并不是简简单单的把值拷贝一份。可以推断,编译器构造的拷贝构造函数是负责做这份工作的。

(3)一个类如果没有任何成员变量和成员函数,那么这个类的大小其实也不是0.因为编译器会偷偷的做一些工作。导致类大小产生额外负担的几个原因是:1.虚函数表的指针。如果类中有虚函数的话,将会在类中保存一个虚函数指针。2:Aligment的限制,为了保证在内存中对其,32位的操作系统要使类的大小是4字节的整数倍,如果类的实际大小没有达到要求的话,编译器会补充一定的空间达到这样的长度要求。3.如果一个类中什么也没有的话,编译器会偷偷的加一个char,占一个字节,这样的话就不会导致同一个类的两个不同的实例占用同一个内存地址。

(4)static成员函数不能被修饰成const,virtual,volatile。 一个类中的纯虚函数也是可以被定义的。

(5)类中virtual函数的引入将导致类的膨胀,如:

Point*
Point::Point(float x ,float y ): _x(x),_y(y)
{
}
将会被扩展成这样子
Point*
Point::Point( Point* this ,float x ,float y )
{
     //设定虚函数表,偷偷加的
     this->_vptr_Point = vtbl_Point;
    //扩展初始化列表
     this_x = x ; 
     this_y = y ;
}


(6)c++的三个著名的扩充是template和exception handling(eh)和runtime type indentification(RTTI)。RTTI是EH的副产品,因为要实现EH就需要在catch中进行匹配,那么就需要RTTI。在template中对于那些没有被使用过的函数是不会实例化出来的,原因是1:空间和时间效率的考虑。如果类中有100个成员函数,但你的程序只针对某个类型使用其中两个,针对另一个类型使用其中五个,那么将其他193个函数都具现将会花费大量的时间和空间。2.尚未实现的机能。并不是一个template具现出来的所有类型就一定能够完整支持一组成员变量所需要的所有运算符,如果只具现那些真正用到的,template就能够支持那些原本可能会造成编译时错误的类型。RTTI提供了downcast操作。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值