zoukankan      html  css  js  c++  java
  • 【C++】对象模型

    前言

      对于传统结构化语言,如C语言,虽然编译器在背后也做了一下事情,但是很好理解。如编译器堆栈建立、参数排列、返回地址、堆栈清楚等。而对于面向对象的语言,编译器背着我们做了太多,如构造函数、析构函数、虚函数、继承、多态、合成额外函数、扩张我们函数的内容等。

      不同的对象模型会有不同的执行效率,因为编译器会根据对象模型对程序做不同的改写。

    C++对象模型

      有如下三种:

     模型一重要!

       一个class对象需要多少内存呢,一般是一下几点的和:

    • nonstatic数据成员的大小之和;
    • 加上由于对齐而产生的填补(与机器有关);
    • 加上为了支持virtual而增加的额外负担(与编译器有关 )。

       另外值得注意的是一个没有nonstatic的类的对象的大小是1,这是被编译器安插的一个char类型,为了让该类的每个对象具有独一无二的内存地址。

     模型二

     模型三

    C++的继承

    • 单继承:如图 class ostream: public ios{...};
    • 多继承:如左图 class iostream: public ostream, public istream{...};此处的需注意,若以图中的继承关系,我们会发现iosteam对象中有两份ios的对象部分,为了解决这个问题就需要virtual base class,也就是虚继承。 
    • 虚继承:如右图 class ostream: virtual public ios{...}; class istream: virtual public ios{...}; 这样无论virtual base class 在继承链中出现多少次,都只会出现一个实体。

       那么加上继承后,derived class object的对象模型是什么样的呢,该如何表现出base class subobject呢?有如下几种模型:

     模型一重要!

    • 对于base class object的nonstatic 数据成员,一般直接放置在derived class object中。
    • 在virtual bass class的原始模型是在class object中为每一个有关联的virtual Base class 加上一个指针。引入对于virtual base class后,对象模型为了维护每一个virtual base class的位置,不是导入一个virtual base class table,就是扩充已存在的virtual table。

       如

     

     模型二

      基于简单模型,增加一个slot,里面存放父类的实体的地址。

      模型三

      每一个子类对象内含一个地址bptr(类似于vptr),指向一个base class table(其中的每个slot对应一个base calss subobject)。

    C++的多态

      在C++中,多态只存在于public的继承体系中。C++用下列方法来支持多态:

    1. 经由一组隐含的转换操作,如把一个derived class指针转化为一个指向其public base 类型的指针。
    2. virtual function机制;
    3. dynamic_cast和typeid运行算符。

        另外指针是C++多态的必要条件

    空类型

      1、一个没有任何数据成员和成员函数的类型的sizeof是1,因为如果我们要使用一个类型的实例,该实例必须在内存中占用一定的空间,否则无法使用。,当然大小也可以比1大,具体由编译器决定。

      2、当在1的基础上,加上非虚成员函数后,sizeof还是不变。

      3、当在1的基础上,加入虚函数后,由于此时需要以指向虚函数表的虚指针,所以sizeof为指针的大小,32位机为4字节,64位机为8字节。

    其他知识点

    C语言中,数据和函数(对数据的操作)是分开的。

      C++同时支持OB和OO两种设计。

      OB :Object Based ,非多态的数据封装模型,就是ADT(Abstract Data Type)的概念,提供了类型对象的一些接口和操作。

      OO :Object Oriented ,支持多态,需要virtual的支持,这导致了内存布局和存取时间上的额外负担。virtual机制包括virtual function机制(用以支持执行期动态绑定),virtual base class (用以实现“对此出现在继承体系中的base class,有一个单一而被共享的实体”)。

      C++中struct和class的用法基本一样,只是继承和成员的默认权限不同,class默认是private继承和private成员,而struct默认是public继承和public成员。

      指针:指针的值是所指对象的首地址,偏移量有指针类型决定。base class的指针可以指向继承体系中的任一类型的对象。

    参考

         《深度探索C++对象模型》

      怀安散人《深度探索C++对象模型》 读书心得 Chapter1

      怀安散人《深度探索C++对象模型》 读书心得 Chapter2

  • 相关阅读:
    「BZOJ1954」Pku3764 The xor – longest Path
    【bzoj4260】【Codechef REBXOR】
    BZOJ_3012_[Usaco2012 Dec]First!
    【bzoj1174】[Balkan2007]Toponyms
    String
    前缀和
    [POI2008] CLO
    [Scoi2010] 游戏
    CodeForces892E
    并查集的删除操作
  • 原文地址:https://www.cnblogs.com/chen-cs/p/13085933.html
Copyright © 2011-2022 走看看