[C++]《深入探索C++面向对象模型》读书笔记

本文是第二遍重读此书的读书笔记,因此只捡了一些自己在重读时仍感重要的知识进行了记录。当然会有些东西遗漏,对我不重要的不一定对每个人都不重要。

PS:这些东西还是需要一定的C++语法基础的。

再PS:页数都是按照侯捷先生的中文版所标。粗体部分乃是重中之重。

================================================================================

【第一章】

在虚拟继承的情况下,base class不管在继承链中被派生多少次,永远只存在一个实体。P11

C++中凡是处于同一个access section的数据,必定保证以其声明次序出现在内存布局中。然而被放置在多个access sections中的各笔数据,排列次序就不一定了。P20

组合,而非继承,才是把C和C++结合在一起的唯一可行方法。P21

Non-public的派生行为以及类型为void*的指针可以说是多态,但他们并没有被语言明白的支持,也就是说它们必须由程序员通过明白的转型操作来管理。P25

C++以以下三种方式支持多态。P25

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

一个指针,不管它指向哪一种数据类型,指针本身所需要的内存大小是固定的。P27

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

类型信息的封装并不是维护于指针之中,而是维护于link之中,此link存在于“object的vptr”和“vptr所指向的virtual table”之间。P32

C++也支持具体的ADT(abstract data type)程序风格,如今被称为object based(OB)。P34

===========================================================================

【第二章】

编译器生成nontrivial default constructor的四种情况:带有default constructormember class object;带有default constructorbase class;带有virtual functionclass;带有一个virtual base classclassP40

(注:关于default constructor三个分支:a.程序员定义了constructor,则肯定不会再生成;b.程序员没有定义constructor,但是编译器合成的是trivial,什么作用都没有;c.程序员没有定义,而且编译器合成了nontrivial的)

 

在合成的default constructor中,只有base class subobjectsmember class objects会被初始化。所有其他的nonstatic data member,如整数、整数指针、整数数组等等都不会被初始化。P47

 

 

程序转化语义学。例如X a(b);转化为X a; a.X::X(b);等。P60

 

 

在严谨的C++用词中,定义是指占用内存的行为。P61

 

编译器会一一操作initialization list(初始化成员列表),以适当的次序在constructor之内安插初始化操作,并且在任何explicit user code(显式的用户代码)之前。List中的项目次序是有classmembers声明次序决定的,不是由initialization list中的排列次序决定的。P77

 

请使用存在于constructor体内的一个member”,而不要使用存在于member initialization list中的member”,来为另一个member设定初值。P80

===========================================================================

【第三章】

“Member rewriting rule”。C++以“member scope resolution rules”来精炼这个“rewriting rule”,其效果是,如果一个inline函数在class声明之后立刻被定义的话,那么就还是对其进行评估的(evaluate)。因此,在一个inline成员函数内部的一个data member绑定操作(e.g. return一个成员变量),会在整个class声明完成之后才会发生。P91

欲对一个nonstatic data member进行存取操作,编译器需要把class object的起始地址加上data member的偏移量(offset)。举个例子,如果 origin._y = 0.0; 那么地址&origin._y将等于 &origin + (&Point3d::_y - 1); 请注意其中的-1操作。指向data member的指针,其offset值总是被加上1,这样可以使编译系统区分出“一个指向data member的指针,用以指向class的第一个member”和“一个指向data member的指针,没有指出任何member”两种情况。P98

C++语言保证“出现在derived class中的base class subobject有其完整原样性”。P102

单一继承提供了一种“自然多态(natural polymorphism)”形式,是关于classes体系中base type和derived type之间的转换。P112

Point3d::*的意思是:指向Point3d data member的指针类型。

(接上)& Point3d::z 和 & origin.z 之间的差异。 取一个nonstatic data member的地址,将会得到它在class中的offset,取一个绑定于真正class object身上的data member的地址,将会得到该member在内存中的真正地址。 P131-P132

===========================================================================

【第四章】

static函数不能:(1)直接存取nonstatic数据;(2)被声明为const。P140

C++的设计准则之一就是:nonstatic member funtion至少必须和一般的nonmember function有相同的效率。P141

inline函数中的局部变量,再加上有副作用的参数,可能会导致大量临时性的对象的产生。(接下页)一个inline函数如果被调用太多次的话,会产生大量的扩展码,使程序的大小暴涨。P187-188

============================================================================

【第五章】

(持续更新中。。。。。。)






你可能感兴趣的:(面向对象)