深度探索C++对象模型-第三章

说明:

​ <u>不是很清楚的点</u>,用下划线。

解答,用斜体;

重点,用粗体加粗;

第二章 Data 语意学

3.2 Data Member 的布局

非静态成员变量在class object中的排列顺序将和其声明的顺序一样的。但C++ standard允许编译器将多个access sections之中的data members自由排列,不必在乎他们的出现在class中的声明顺序。

3.3 Data Member 的存取

存取代价:

每一个member 的存取许可(private public protected),以及与class的关联,并不会导致任何空间上或执行时间上的额外负担——不论是在个别的class objects 或是在static data member 本身。

static data members:

静态数据成员(static data members) 被视为global变量,只有一个实体,存放在程序的data segment(数据段)之中,每次取static member 就会被内部转化为对该唯一的extern 实体的直接参考操作。若取一个static data member的地址,会得到一个数据类型的指针,而不是只想起class member的指针。

nonstatic data members:

只要程序猿在一个成员函数中直接处理一个非静态成员变量,“隐式类对象(this指针)”就会出现。

欲对一个nonstatic data member 进行存取操作,编译器需要把this指针(class object的起始地址)加上data member的偏移量。

非静态成员变量的偏移量在编译时期就可以获知,即使这个成员变量是属于被派生的类。因此存取效率高。

3.4 继承 与 Data Member

class Point2d{
    public:
        //....
    private:
        float x,y;
}
class Point3d{
    public:
        //....
    private:
        float x,y,z;
}

讨论上述结构,与 “提供继承结构” 有什么不同?

下面分四种情况讨论。

1.只要继承不要多态

具体继承(相对于虚拟继承)并不会增加空间或存储时间上的额外负担。这种情况base class和derived class的objects都是从相同的地址开始,其差异只在于derived object 比较大,用以容纳自建的静态数据成员,把一个derived class object指定给base class 的指针或引用(一定要通过指针或引用),并不需要编译器去调停或修改地址,提供了最佳执行效率。

2.加上多态

即在继承关系中,提供一个虚函数接口。

多态带来了程序弹性,但这种弹性会带来空间和存取时间的额外负担:

  1. 导入一个虚函数表 ,用来存储它所声明的每一个virtual functions的地址。
  2. 在每一个class object中导入一个vptr,提供执行期的链接,使每一个object能够找到相应的virtual table。
  3. 加强constructor,使它能够为vptr设定初始值,让它指向class 所对应的virtual table 。
  4. 加强destructor,使它能够消抹“指向class 相关virtual table”的vptr。

3.多重继承

class point2d{
    public:
        //....
    protected:
        float x,y;
}
class Vertex{
    public:
        //....
    protected:
        Vertex *next;
}
class Vertex3d: public point2d, public Vertex{ 
    //point2d是第一个base class,Vertex是第二个
    public:
        //....
    protected:
        float mumble;
}

对于一个多重派生对象,将其地址指定给“最左端(第一个)base class的指针”,情况和单一继承时相同,因为二者都指向了相同的起始地址;至于第二个或后面的base class 的地址指定操作,则需要将地址修改过:加上(<u>或减去,如果是downcast</u>)介于中间的base class subobject(s)的大小。

如果要存取第二个(或后面)的base class 中的一个data member ,会增加额外的成本吗?不需要付出额外的成本,因为members的位置在编译时期就固定了,因此存取member只是一个简单的offset的运算。

4.虚拟继承

这一部分比较难,并且各个编译器实现方式不同。

class如果含有一个或多个 virtual base class subobjects 将被分割为两部分:一个不变区域和一个共享区域。

  • 不变区域中的数据,不管后继如何衍化,总是能有固定的offset,这部分可以被直接存取;
  • 至于共享区域,所表现的就是virtual base class subobject ,这个部分数据,其位置因为每次派生操作而有变化,所以只能间接存取。

总结:

虚拟继承内存布局
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,501评论 6 544
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,673评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,610评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,939评论 1 318
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,668评论 6 412
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,004评论 1 329
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,001评论 3 449
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,173评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,705评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,426评论 3 359
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,656评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,139评论 5 364
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,833评论 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,247评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,580评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,371评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,621评论 2 380

推荐阅读更多精彩内容