您的位置:首页 > 移动开发 > Objective-C

读书摘要--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 下表现不佳。

    任何解决方案如果是以程序操作为基础,导致较高的复杂度和较大的错误倾向,一般公认,这表明语言在该方面存在弱点。

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息