《深度探索C++对象模型》读书笔记

原创 2016年08月28日 18:25:29

第三章(The Semantics of Data)

一个空的class的大小并不为0;

class x {   };//sizeof(x) = 1;
即空的class并不是真的空,它有一个隐晦的1bytes,那是编译器安插进去的一个char,这使得这个class的两个objects得以在内存中配置独一无二的地址:

X a, b;
if(&a == &b) cout << "error" << endl;

class的大小受到三个因素的影响:

  • 语言本身所造成的额外负担,virtual(vptr)
  • 编译器对于特殊情况所提供的优化处理(比如空class中插入一个char)
  • Alignment的限制(对齐的限制)

注意:nonstatic data members和继承而来的nonstatic data members(不论是virtual或nonvirtual base class), 都会直接存放在每个class object之中。static data members,被放置在程序的一个global data segment中,不会影响个别的class object的大小,不管class产生多少个objects(直接或间接产生),static data members永远只存在一份实体。

Point3d origin, *pt = &origin;
(1)origin.x = 0.0;
(2)pt->x = 0.0
那么通过origin存取和通过pt存取,有差别吗?答案是有

每一个nonstatic data member的偏移量(offset)在编译时期即可获知,甚至如果member属于一个base class subobject也奕扬,因此存取一个nonstatic data member,其效率和存取一个C struct member获一个nonderived class的member是一样的。(1)可以确定编译期间就可以知道其是origin的x,固定的;(2)如果x是从virtual base class继承来的,那么pt指向哪一个class type?所以这个操作必须延迟到执行期,(vptr)才能知道。


静态成员在使用前必须要进行初始化,在class内进行定义,在class外进行初始化

class A{
public:
    static int x;
};
int A::x = 1;
注意初始化的方式,程序中使用使,使用A::x即可,如果考虑继承或者虚继承,也永远记住:静态成员只有唯一一个实体(如果有继承不管使用base::x还是driverd::x得到值都是一个值

容易犯的一个错误是,把一个class分解为两层或更多层,有可能会膨胀所需空间。


多态的开销

多态会带来的开销:

  1. 每个 class有一个与之相关的vitual table(虚函数表),用来存放它所声明的每一个virtual functions的地址, table的元素数目通常是virtual functions的数目
  2. 在每一个class object中导入一个vptr,提供执行期间的链接,使每个object能够找到相应的virtual table
  3. 加强constructor函数,使它能够为vptr设定初值
  4. 加强destructor函数
对于单继承,base class和derived class的objects都是从相同的地址开始,其间差异在于derived object比较大,用以容纳它自己的nonstatic data members,
 dervied A;
 base *B = &A;让基类指针指向派生类很自然。但是如果base中没有虚函数,而derived中有虚函数,那么这种规则就可能被打破,因为derived object中有一个vptr,vptr的插入可能会打破内存布局,那么此时进行转换时,就需要编译器的介入。多重继承更是打破这种布局。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

《深度探索C++对象模型》读书笔记(1)

《深度探索C++对象模型》读书笔记(1)。   在C++中,有两种class data members:static和nonstatic,以及三种class member functi...

《深度探索C++对象模型》读书笔记

1,  在Stroustrup当初设计的C++对象模型中,Nonstatic data members被配置于每一个class object之内,static data members则被存放在所...

《深度探索C++对象模型》读书笔记——Function 语意学【for_wind】

Member的各种调用方式

《深度探索C++对象模型》读书笔记之Function语意学

C++支持三种类型的成员函数:static、nonstatic、virtual   1、C++的设计准则中说:非静态成员函数至少必须和一般的非成员函数有相同的效率。这是如何做到的? C+...

【读书笔记】深度探索C++对象模型(更新中

第三章 Data 语义学先看栗子下面通过几个例子大概展示了C++对象内存布局在复杂的继承关系中使用的策略。 开始之前,先来读读下面这段话 C++ Standard 并不强制规定如 “base c...

《深度探索C++对象模型》读书笔记(2)。

default constructor仅在编译器需要它时,才会被合成出来。    通常来说,由编译器合成出来的default constructor是没啥用的(trivial),但有以下几种例外...

深度探索c++对象模型读书笔记(一)

深度探索c++对象模型读书笔记(一)1.c++有两种class data menmbers:static 和 nonstatic 三种class menmber functions:static ...
  • Mimahoo
  • Mimahoo
  • 2017年03月27日 15:16
  • 373

【深度探索C++对象模型读书笔记】【第5章】构造、析构、拷贝语意学

1、 一般而言,class的data member应该被初始化,而且只在constructor中或其它member functions中初始化,其它任何操作都将破坏其封装性质,使其维护和修改更加困难。...

【深度探索C++对象模型读书笔记】【第3章】Data语意学

1、例子,用VS 2013编译器 #include using namespace std; class X{}; class Y :public virtual X{}; class Z :pu...

《深度探索C++对象模型》读书笔记(1)仅含前四章

1.C++对虚拟基类的支持会导致一点额外的负担,具体实现是在派生类对象中使用一个指针来指向对应的虚拟基类,这个指针指向一个表格,表格存放的是引导访问虚拟基类子对象的信息,例如其在派生类对象中的偏移量或...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《深度探索C++对象模型》读书笔记
举报原因:
原因补充:

(最多只允许输入30个字)