读书摘要--Inside The C++ Object Model
2008-04-05 12:14
471 查看
Chp 1 关于对象
1.1 C++对象模式
每个类对应的type_info对象,通常由Vtable的第一个slot指向。
1.2 关键字所带来的差异
如果不是为了努力维持与C的兼容性,C++远可以比现在更简单些。
C++标准保证,同一个access section[/b]中的数据成员,其内存布局同其声明次序保持一致。
组合,而非继承,才是将C和C++的内存布局结构结合在一起唯一可行的方法。
1.3 对象的差异
转型操作在大多数情况下不会改变指针所含的地址内容,改变的只是编译器对"指针所指向的内存的大小和内容"的解释方式。
OO(Object-Oriented)和OB(Object-Oriented)的区别集中体现在弹性和效率[/b]上。
Chp 2 构造函数语意学
2.1 Default Constructor
被编译器合成出来的Default Constructor的目的是满足编译器的需要,而不是程序的需要[/b]。
4种合成的 non-trivial default constructor[/b]
1. 类中包含对象成员,其具有defalut constructor
2. 类的base class具有default constructor
2. 类包含virtual function
3. 类具备virtual base class
除此四种情况之外,对于未显式声明default constructor 的类,其在语义上拥有implicit trivial default constructor,但实际上这些constructor并不会被合成出来。
常见的两个误解:[/b]
1.任何类如果程序员没有定义default constructor,就会被编译器合成出一个来。
2.编译器合成出来的default constructor,会将class内的每个data member都设定为默认值。
2.2 copy constructor 语意学
2.2.1[/b] Default Member-wise Initialization(递归进行)
类似于default constructor,C++标准也将copy constructor分为 trivial 和non-trivial,只有non-trivial的才会被合成出来
而判断一个copy constructor是否 trivial的标准则是,class是否具备"bitwise copy semantics[/b]"
2.2.3 不要bitwise copy semantics!
以下四种情况下,class不具备"bitwise copy semantics"
1.class包含一个member object,且后者具备copy constructor
2.class的base class具有copy constructor
3.class具有virtual function
4.class具有virtual base class
2.2.4 重新设定 vptr 指针
当class具备了vtable后,该class就不再具备 bitwise copy semantics。[/b]
2.3 程序转换语意学
2.3.2 参数的初始化
语意:copy-initialization
相同语意前提下的两种实现机制: 1.临时对象 2 直接构建
2.3.3 返回值的初始化
NRV(Named return value)优化:将copy constructor的调用优化掉,直接对要返回的对象执行各种操作。
注,通常NRV优化的启用,是以class具备copy constructor为前提的
一般而言,对于copy constructor 的优化,标准允许实现有很大的自由发挥空间。这样的好处在于获得机器码效率的提升,缺点在于无法安全的在copy constructor 中引入副作用并期望其一定会发生。
2.4 成员初始化列表
编译器会一一操作初始化列表的成员,以适当的顺序在class的constructor中插入初始化操作,并且保证它们都发生在任何explicit user code 之前。
Chp 3 Data语意学
3.4 继承与Data Member
一般而言,任何规则碰到virtual base class 都要例外[/b]
3.4.2 加上多态的继承
vptr在对象中放在什么位置才好?
选择1 放在class object 的尾部
优点:保持内存布局与C最大程度的一致
缺点:不利于实现virtual inheritance
选择2 放在class object 的头部
优点:易于实现virtual inheritance 和multiple inheritance
缺点:丧失了和C的内存布局兼容性
3.4.3 多重继承
自然多态(natural polymorphism)[/b]:derived class pointer 到base class pointer 的转换无需编译器对指针指向的地址进行调整
多重继承的主要麻烦在于derived class object和继承列表中第二个或更靠后的base class object之间的地址转换关系。
3.4.4 虚拟继承
一如语意表面的复杂度,编译器要支持虚拟继承,难度也是很高的。
实现虚拟继承的一般方法: 若一个class拥有virtual base class ,则该class 的对象被分割成两部分: invariant region 和 shared region。
invariant region中的数据,无论后继如何派生,都拥有固定的offset(从object的头部算起)
shared region 则代表 virtual base class object,这一部分的数据,其位置与后续派生有关,无法直接存取,而只能间接存取
一般而言,virtual base class 最有效的应用形式是:一个抽象的virtual base,不包含任何data member
3.6 指向data member 的指针
对于指向 data member 的指针,实际上是data member在 class object中的偏移量;更确切的说,是 offset +1——也就是说,位于object 头部的成员对应的data member pointer 的值为1
这种位移从1开始的特性()是基于如下考虑:如何区分"没有指向任何data member"的data member pointer 和 "指向第一个data member "的data member pointer?
Chp 4 Function语意学
4.1 Member Function的各种调用方式
4.1.1 Non-static member function[/b]
C++的设计准则之一,就是non-static member function 的调用至少必须和一般的non-member function 有一样的效率。
编译器在内部会将 "non-static member function" 转化为等价的"non-member function"
4.1.2 Virtual member function[/b]
4.1.3 Static member function[/b]
4.2 Virtual member functions
在单一继承体系中, virtual function 机制运转良好;然而在多重继承和虚继承中,对 Virtual Function的支持就不是如此简单了
4.2.1 多继承体系下的Virtual Function
问题的复杂性,来自于第二个及后继base class身上,以及"必须在运行期调整this指针"。
问题1 virtual destructor[/b]
解决调整this指针较有效率的解决方案是thunk技术[/b],即一小段汇编代码,其负责完成两个任务:(1) 调整this指针 (2) 调用对应的函数
利用thunk技术, vtable 中的slot就可以继续简单的包含一个指针,这个指针可能直接指向一个virtual function,也可能指向一个相关的thunk(如果该virtual 需要调整this指针的话)。
4.4 指向Member function的指针
取一个non-static member function的地址,得到的是其在内存中的位置。
static member function 对应着普通的函数指针,而不是"成员指针"。
virtual function,multiple inheritance 和virtual inheritance 的存在,会导致member function 指针变得非常复杂。
4.4.1 指向"virtual member function"的指针[/b]
对一个"virtual member function"取地址,得到的是只是vtable的一个索引值[/b],并不是内存地址。
Chp 5 构造、析构、拷贝语意学
纯虚函数可以被静态调用,但无法动态调用。
5.1 无继承体系下的对象构造
vptr的初始化由编译器在constructor中插入的代码完成;这些代码位于base class constructor的调用之后,但在任何user code之前。
既然标准保证在member initialization list对应的代码执行前,该对象的vptr已经被正确的设置好,那么在member
initialization list中调用virtual member
function,从vptr的角度来看,是安全的;但如果考虑到可能存在的member之间的依赖关系,这种风格显然是不安全、不推荐使用的。
一般而言,如果程序中频繁的在函数中返回一个local class object,那么在设计class时,提供一个copy constructor就比较合理,它的存在会触发NRV优化。
5.3 对象复制语意学
一个class的默认assignment operator,在如下情况下不具备bitwise copy语意[/b]:
1. class含有一个member object,且其具有assignment ooprator
2. class的base class 具有 assignment operator
3. class包含virtual function
4. class有virtual base class
概括的说,non-trivial的assignment operator 不具备bitwise copy semantics。只有non-trivial的assignment operator 才会被编译器合成出来。
需要注意的时,并不存在与member initialization list 相对应的copy assignment list。
assignment operator 在 virtual inheritance 下表现不佳。
任何解决方案如果是以程序操作为基础,导致较高的复杂度和较大的错误倾向,一般公认,这表明语言在该方面存在弱点。
1.1 C++对象模式
每个类对应的type_info对象,通常由Vtable的第一个slot指向。
1.2 关键字所带来的差异
如果不是为了努力维持与C的兼容性,C++远可以比现在更简单些。
C++标准保证,同一个access section[/b]中的数据成员,其内存布局同其声明次序保持一致。
组合,而非继承,才是将C和C++的内存布局结构结合在一起唯一可行的方法。
1.3 对象的差异
转型操作在大多数情况下不会改变指针所含的地址内容,改变的只是编译器对"指针所指向的内存的大小和内容"的解释方式。
OO(Object-Oriented)和OB(Object-Oriented)的区别集中体现在弹性和效率[/b]上。
Chp 2 构造函数语意学
2.1 Default Constructor
被编译器合成出来的Default Constructor的目的是满足编译器的需要,而不是程序的需要[/b]。
4种合成的 non-trivial default constructor[/b]
1. 类中包含对象成员,其具有defalut constructor
2. 类的base class具有default constructor
2. 类包含virtual function
3. 类具备virtual base class
除此四种情况之外,对于未显式声明default constructor 的类,其在语义上拥有implicit trivial default constructor,但实际上这些constructor并不会被合成出来。
常见的两个误解:[/b]
1.任何类如果程序员没有定义default constructor,就会被编译器合成出一个来。
2.编译器合成出来的default constructor,会将class内的每个data member都设定为默认值。
2.2 copy constructor 语意学
2.2.1[/b] Default Member-wise Initialization(递归进行)
类似于default constructor,C++标准也将copy constructor分为 trivial 和non-trivial,只有non-trivial的才会被合成出来
而判断一个copy constructor是否 trivial的标准则是,class是否具备"bitwise copy semantics[/b]"
2.2.3 不要bitwise copy semantics!
以下四种情况下,class不具备"bitwise copy semantics"
1.class包含一个member object,且后者具备copy constructor
2.class的base class具有copy constructor
3.class具有virtual function
4.class具有virtual base class
2.2.4 重新设定 vptr 指针
当class具备了vtable后,该class就不再具备 bitwise copy semantics。[/b]
2.3 程序转换语意学
2.3.2 参数的初始化
语意:copy-initialization
相同语意前提下的两种实现机制: 1.临时对象 2 直接构建
2.3.3 返回值的初始化
NRV(Named return value)优化:将copy constructor的调用优化掉,直接对要返回的对象执行各种操作。
注,通常NRV优化的启用,是以class具备copy constructor为前提的
一般而言,对于copy constructor 的优化,标准允许实现有很大的自由发挥空间。这样的好处在于获得机器码效率的提升,缺点在于无法安全的在copy constructor 中引入副作用并期望其一定会发生。
2.4 成员初始化列表
编译器会一一操作初始化列表的成员,以适当的顺序在class的constructor中插入初始化操作,并且保证它们都发生在任何explicit user code 之前。
Chp 3 Data语意学
3.4 继承与Data Member
一般而言,任何规则碰到virtual base class 都要例外[/b]
3.4.2 加上多态的继承
vptr在对象中放在什么位置才好?
选择1 放在class object 的尾部
优点:保持内存布局与C最大程度的一致
缺点:不利于实现virtual inheritance
选择2 放在class object 的头部
优点:易于实现virtual inheritance 和multiple inheritance
缺点:丧失了和C的内存布局兼容性
3.4.3 多重继承
自然多态(natural polymorphism)[/b]:derived class pointer 到base class pointer 的转换无需编译器对指针指向的地址进行调整
多重继承的主要麻烦在于derived class object和继承列表中第二个或更靠后的base class object之间的地址转换关系。
3.4.4 虚拟继承
一如语意表面的复杂度,编译器要支持虚拟继承,难度也是很高的。
实现虚拟继承的一般方法: 若一个class拥有virtual base class ,则该class 的对象被分割成两部分: invariant region 和 shared region。
invariant region中的数据,无论后继如何派生,都拥有固定的offset(从object的头部算起)
shared region 则代表 virtual base class object,这一部分的数据,其位置与后续派生有关,无法直接存取,而只能间接存取
一般而言,virtual base class 最有效的应用形式是:一个抽象的virtual base,不包含任何data member
3.6 指向data member 的指针
对于指向 data member 的指针,实际上是data member在 class object中的偏移量;更确切的说,是 offset +1——也就是说,位于object 头部的成员对应的data member pointer 的值为1
这种位移从1开始的特性()是基于如下考虑:如何区分"没有指向任何data member"的data member pointer 和 "指向第一个data member "的data member pointer?
Chp 4 Function语意学
4.1 Member Function的各种调用方式
4.1.1 Non-static member function[/b]
C++的设计准则之一,就是non-static member function 的调用至少必须和一般的non-member function 有一样的效率。
编译器在内部会将 "non-static member function" 转化为等价的"non-member function"
4.1.2 Virtual member function[/b]
4.1.3 Static member function[/b]
4.2 Virtual member functions
在单一继承体系中, virtual function 机制运转良好;然而在多重继承和虚继承中,对 Virtual Function的支持就不是如此简单了
4.2.1 多继承体系下的Virtual Function
问题的复杂性,来自于第二个及后继base class身上,以及"必须在运行期调整this指针"。
问题1 virtual destructor[/b]
解决调整this指针较有效率的解决方案是thunk技术[/b],即一小段汇编代码,其负责完成两个任务:(1) 调整this指针 (2) 调用对应的函数
利用thunk技术, vtable 中的slot就可以继续简单的包含一个指针,这个指针可能直接指向一个virtual function,也可能指向一个相关的thunk(如果该virtual 需要调整this指针的话)。
4.4 指向Member function的指针
取一个non-static member function的地址,得到的是其在内存中的位置。
static member function 对应着普通的函数指针,而不是"成员指针"。
virtual function,multiple inheritance 和virtual inheritance 的存在,会导致member function 指针变得非常复杂。
4.4.1 指向"virtual member function"的指针[/b]
对一个"virtual member function"取地址,得到的是只是vtable的一个索引值[/b],并不是内存地址。
Chp 5 构造、析构、拷贝语意学
纯虚函数可以被静态调用,但无法动态调用。
5.1 无继承体系下的对象构造
vptr的初始化由编译器在constructor中插入的代码完成;这些代码位于base class constructor的调用之后,但在任何user code之前。
既然标准保证在member initialization list对应的代码执行前,该对象的vptr已经被正确的设置好,那么在member
initialization list中调用virtual member
function,从vptr的角度来看,是安全的;但如果考虑到可能存在的member之间的依赖关系,这种风格显然是不安全、不推荐使用的。
一般而言,如果程序中频繁的在函数中返回一个local class object,那么在设计class时,提供一个copy constructor就比较合理,它的存在会触发NRV优化。
5.3 对象复制语意学
一个class的默认assignment operator,在如下情况下不具备bitwise copy语意[/b]:
1. class含有一个member object,且其具有assignment ooprator
2. class的base class 具有 assignment operator
3. class包含virtual function
4. class有virtual base class
概括的说,non-trivial的assignment operator 不具备bitwise copy semantics。只有non-trivial的assignment operator 才会被编译器合成出来。
需要注意的时,并不存在与member initialization list 相对应的copy assignment list。
assignment operator 在 virtual inheritance 下表现不佳。
任何解决方案如果是以程序操作为基础,导致较高的复杂度和较大的错误倾向,一般公认,这表明语言在该方面存在弱点。
相关文章推荐
- 读书摘要--Inside The C++ Object Model
- 《inside the c++ object model》读书笔记 之一:对象
- Inside The C++ Object Model 读书笔记
- 《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记
- Inside the C++ Object Model.pdf
- Inside The C++ Object Model ---- Object Lessons
- 《Inside the C++ Object Model》关于基类与派生类的Tips
- Inside The C++ Object Model(四)
- Inside the C++ Object Model学习笔记[Chap2.4]
- Inside the C++ Object Model学习笔记[Chap6]
- Inside the C++ Object Model 深度探索对象模型 5-Construction 6-Runtime 7-Object
- 读书笔记《Inside the C++ Object Model》:Copy Constructor的构造操作
- Inside The C++ Object Model(四)函数语意学
- 《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记
- 《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记
- C++对象模型,很多东西来自《Inside the C++ Object Model》一书
- Inside The C++ Object Model 学习笔记 -- 关于对象
- 《inside the c++ object model》读书笔记 之二:构造函数
- 构造、解构、拷贝语意学(inside the c++ object model)
- Inside The C++ Object Model ---- Object Lessons