设为首页 加入收藏

TOP

关于C++对象模型的深入理解(四)
2018-03-14 09:00:23 】 浏览:788
Tags:关于 对象 模型 深入 理解
py constructor的出现才会激活C++编译器的NRV优化!NRV优化虽然极大地改善了效率,但还是饱受批评:一是优化由编译器默默完成,而是否完成以及其完成程度完全透明;二是一旦函数变得比较复杂,优化就变得较难施行;三是优化由可能使程序产生错误——有时并不是对称地调用constructor和destructor,而是copy constructor未被调用!

5.在编译器提供NRV优化的前提下,如果可以预见class需要大量的memberwise初始化操作,比如以by value的方式传回objects,那么提供一个explicit inline copy constructor的函数实体就非常合理。此种情况下,没有必要同时提供explicit assignment operator定义。

6.copy constructor的应用迫使编译器多多少少对程序代码作部分优化,尤其是当一个函数以by value的方式传回一个class object,而该class有一个copy constructor(或定义或合成)时,无论在函数的定义还是在使用上将导致深奥的程序转化。此外,编译器将实施NRV优化。

7.注意正确使用memset()和memcpy(),它们都只有在classes不含任何由编译器产生的内部members如vptr时才能有效运行!

2002-6-30

2.4成员初始化列表

1.当写下一个constructor时,就有机会设定class members的初值。不是经由member initialization list,就是在constructor函数本身之内。

2.下列情况,为了让程序能被顺利编译,必须使用member initialization list:

ü初始化一个reference member时;

ü初始化一个const member时;

ü调用一个base class的constructor,而它拥有一组参数时;

ü调用一个member class的constructor,而它拥有一组参数时。

3.编译器会对initialization list一一处理并可能重新排序,以反映出members的声明次序,它会安插一些代码到constructor内,并置于任何explicit user code之前。

4.一个忠告:请使用“存在于constructor体内的一个member”,而不是“存在于member initialization list中的一个member”,来为另一个member设定初值。

2002-7-1

Data语意学The Semantics of Data

讨论如下继承体系:

class X{};

class Y : public virtual X{};

class Z : public virtual X{};

class A: public Y, public Z{};

1.一个empty class如class X{},它有一个隐晦的1 byte,那是被编译器安插进去的一个char,使得这个class的两个objects得以在内存中配置独一无二的地址。

2.Y和Z的大小受到三个因素的影响:

ü语言本身所造成的额外负担overhead。语言支持virtual base classes时导致的额外负担反映在某种形式的指针身上,它要么指向virtual base class subobject,要么指向一个存放virtual base class subobject地址或者其偏移量offset的表格。

ü编译器对于特殊情况所提供的优化处理。virtual base class X 1 byte大小的subobject也出现在class Y和Z身上。传统上它被放在derived class的固定部分的尾端。某些编译器对empty virtual base提供特殊处理,将它视为derived class object最开头的一部分,它不用会任何的额外空间,也就是前面提到的1 byte。

üAlignment的限制。Alignment就是将数值调整到某数的整数倍,在32位计算机上,通常该数为4 bytes(32位),以使bus的运输量达到最高效率。

3.一个virtual base class subobject只会在derived class中存在一份实体,不管它在class继承体系中出现了多少次,class A的大小由下列几点决定:

ü被大家共享的唯一一个class X实体,大小为1 byte;

üBase Y、Z的大小减去因virual base class而配置的大小;

üclass A自己的大小;

üclass A的alignment数量。

4.C++ standard并不强制规定base class subobjects、不同存取级别的data members的排列次序这种琐碎细节,它也不规定virtual function以及virtual base classes的实现细节。

5.C++对象模型尽量以空间优化和存取速度优化来表现nonstatic data members,并且保持和C语言struct数据配置的兼容性。它把数据直接存放在每一个class object中,对于继承而来的nonstatic data members,不管是virtual或nonvirtual base class也是如此。至于static data members则被放置在程序的一个global data segment中,不会影响个别class object的大小。static data member永远只存在一份实体,但是一个template class的static data member的行为稍有不同。

3.1 Data Member的绑定

inline member function躯体内的data member绑定操作,会在整个class声明完成后才发生,而argument list中的名称还是会在它们第一次遭遇时被适当地决议resolved完成。基于这种状况,请始终把nested type声明放在class的起始处。

2002-7-2

3.2 Data Member的布局

1.每一个private、protected、public区段就是一个access section。C++ Standard要求,在同一个access section中,members的排列只需满足“较晚出现的members在class object中有较高的地址”这一条件即可。也就是说各个members并不一定的连续排列,alignment可能需要的bytes以及编译器可能合成供内部使用的data members都可能介于被声明的members之间。

2.C++ Standard也允许编译器将多个access sections之中的data members自由排列,不必在乎它们出现在class声明中的次序。当前各家编译器都是把一个以上的access sections连锁在一起,依照声明的次序成为一个连续区块。access sections的多寡不会导致额外负担。

3.vptr传统上会被放在所有明确声明的members的最后,不过如今也有一些编译器把vptr放在class object的最前端。

4.一个用来判断哪

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 4/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇万能的C++头文件分享 下一篇C++设计模式之原型模式(克隆羊多..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目