• C++对象模型


    1.类布局

    1.1简单类对象的内存布局

    class A
    {
    public:
        void f();
    private:
        int i;
        char c;
        static int s;
    };

    简单对象的内存布局:非静态(staic)成员变量,按照其在类中声明的顺序,加上字节对齐,依次分布在内存中。

    1.2含有虚函数类对象的内存布局。

    class A
    {
    public:
        void f();
        virtual void vf();
    private:
        int i;
        char c;
        static int s;
    };

    带有虚函数对象的内存布局:在实例的起始内存位置放置一个4字节大小的空间用来保存虚函数表的地址。

    1.3 多继承或单继承。

    class A
    {
    public:
        void f();
        virtual void vf();
    private:
        int i;
        char c;
        static int s;
    };
    
    class B :public A
    {
    public:
        int b;
        virtual void vb();
    };

    每个派生类的实例中都包含了一份完整的基类实例数据。

    MSC++ 保证任何继承自有虚函数的类的第一项永远是vfptr,例如 class A:public B, public C   如果C含有虚函数,那么C实例在A实例的前面。

    MSC++实例对象会共享或重用从基类继承来的vfptr,但是在多重继承下,一个实例可能包含多个vfptr。

    MSC++中,如果派生类的某个函数覆盖了多个基类的虚函数时,这时候会使用调整块。但只是覆盖非最左的基类的虚函数时,MSC++一般不创建调整块,采用接受嵌套在派生类实例中的非最左基类的指针。

    MSC++虚拟继承可能还会涉及调整块。

    MSC++派生类中的新虚函数不会共用虚继承基类的虚函数表,而是新建一个虚函数表。放在实例顶端。

    2.函数调用

    对于非虚成员函数来说,调用哪个成员函数是在编译时,根据-> 操作符左边的指针表达式的类型静态决定;决定隐藏的this参数类型。

    对于虚函数调用来说,调用的虚函数是由指针实际指向的实例类型所决定。

  • 相关阅读:
    转 [Lucene.Net] 基本用法
    万商网与Alibaba等的比较
    B2B闯入者 新势力正在崛起
    项目管理随想一
    【转载】/proc目录中的重要信息
    文件名乱码转换器
    C函数调用中对入参取地址引发的问题
    编译通过的代码不算什么,一眼能看懂的代码才算好代码
    Handler使用
    删除system/app下的apk
  • 原文地址:https://www.cnblogs.com/kobe-echo/p/5089557.html
Copyright © 2020-2023  润新知