• C++虚表详解


    所有结果均为32位系统,指针为4个字节

    简单继承

    class A {
    public:
      int a;
    };
    
    class B : public A {
    public:
      int b;
    };
    

    对象B的内存布局:

    b --> +-----------+
          |     a     |
          +-----------+
          |     b     |
          +-----------+
    

    简单继承虚函数

    class A {
    public:
      int a;
      virtual void v();
    };
    
    class B : public A {
    public:
      int b;
    };
    

    对象B内存布局

    /*                    
                               +-----------------------+
                               |     0 (top_offset)    |
                               +-----------------------+
    b --> +----------+         | ptr to typeinfo for B |
          |  vtable  |-------> +-----------------------+
          +----------+         |         A::v()        |
          |     a    |         +-----------------------+
          +----------+
          |     b    |
          +----------+
    

    简单多重继承

    class A {
    public:
      int a;
      virtual void v();
    };
    
    class B {
    public:
      int b;
      virtual void w();
    };
    
    class C : public A, public B {
    public:
      int c;
    };
    

    对象C的内存布局

    /*
    
                               +-----------------------+
                               |     0 (top_offset)    |
                               +-----------------------+
    c --> +----------+         | ptr to typeinfo for C |
          |  vtable  |-------> +-----------------------+
          +----------+         |         A::v()        |
          |     a    |         +-----------------------+
          +----------+         |    -8 (top_offset)    |
          |  vtable  |---+     +-----------------------+
          +----------+   |     | ptr to typeinfo for C |
          |     b    |   +---> +-----------------------+
          +----------+         |         B::w()        |
          |     c    |         +-----------------------+
          +----------+
    

    简单多重继承(虚函数)

    
    class A {
    public:
      int a;
      virtual void v();
    };
    
    class B {
    public:
      int b;
      virtual void w();
    };
    
    class C : public A, public B {
    public:
      int c;
      void w();
    };
    

    对象C的内存布局:

    /*
    
                               +-----------------------+
                               |     0 (top_offset)    |
                               +-----------------------+
    c --> +----------+         | ptr to typeinfo for C |
          |  vtable  |-------> +-----------------------+
          +----------+         |         A::v()        |
          |     a    |         +-----------------------+
          +----------+         |         C::w()        |
          |  vtable  |---+     +-----------------------+
          +----------+   |     |    -8 (top_offset)    |
          |     b    |   |     +-----------------------+
          +----------+   |     | ptr to typeinfo for C |
          |     c    |   +---> +-----------------------+
          +----------+         |    thunk to C::w()    |
                               +-----------------------+
    
    

    菱形继承

    class A {
    public:
      int a;
      virtual void v();
    };
    
    class B : public A {
    public:
      int b;
      virtual void w();
    };
    
    class C : public A {
    public:
      int c;
      virtual void x();
    };
    
    class D : public B, public C {
    public:
      int d;
      virtual void y();
    };
    

    对象D的内存布局:

    /*
    
                               +-----------------------+
                               |     0 (top_offset)    |
                               +-----------------------+
    d --> +----------+         | ptr to typeinfo for D |
          |  vtable  |-------> +-----------------------+
          +----------+         |         A::v()        |
          |     a    |         +-----------------------+
          +----------+         |         B::w()        |
          |     b    |         +-----------------------+
          +----------+         |         D::y()        |
          |  vtable  |---+     +-----------------------+
          +----------+   |     |   -12 (top_offset)    |
          |     a    |   |     +-----------------------+
          +----------+   |     | ptr to typeinfo for D |
          |     c    |   +---> +-----------------------+
          +----------+         |         A::v()        |
          |     d    |         +-----------------------+
          +----------+         |         C::x()        |
                               +-----------------------+
    

    菱形继承(虚继承)

    class A {
    public:
      int a;
      virtual void v();
    };
    
    class B : public virtual A {
    public:
      int b;
      virtual void w();
    };
    
    class C : public virtual A {
    public:
      int c;
      virtual void x();
    };
    
    class D : public B, public C {
    public:
      int d;
      virtual void y();
    };
    

    对象D的内存布局:

    /*
    
                                       +-----------------------+
                                       |   20 (vbase_offset)   |
                                       +-----------------------+
                                       |     0 (top_offset)    |
                                       +-----------------------+
                                       | ptr to typeinfo for D |
                          +----------> +-----------------------+
    d --> +----------+    |            |         B::w()        |
          |  vtable  |----+            +-----------------------+
          +----------+                 |         D::y()        |
          |     b    |                 +-----------------------+
          +----------+                 |   12 (vbase_offset)   |
          |  vtable  |---------+       +-----------------------+
          +----------+         |       |    -8 (top_offset)    |
          |     c    |         |       +-----------------------+
          +----------+         |       | ptr to typeinfo for D |
          |     d    |         +-----> +-----------------------+
          +----------+                 |         C::x()        |
          |  vtable  |----+            +-----------------------+
          +----------+    |            |    0 (vbase_offset)   |
          |     a    |    |            +-----------------------+
          +----------+    |            |   -20 (top_offset)    |
                          |            +-----------------------+
                          |            | ptr to typeinfo for D |
                          +----------> +-----------------------+
                                       |         A::v()        |
                                       +-----------------------+
    
    • 这里需要注意,因为A中有虚函数,所以虚基类A前面必须带有虚表指针。

    如果A中没有虚函数

    class A {
    public:
      int a;
      void v();
    };
    
    class B : public virtual A {
    public:
      int b;
      virtual void w();
    };
    
    class C : public virtual A {
    public:
      int c;
      virtual void x();
    };
    
    class D : public B, public C {
    public:
      int d;
      virtual void y();
    };
    

    对象D的内存布局:

    /*
    
                                       +-----------------------+
                                       |   20 (vbase_offset)   |
                                       +-----------------------+
                                       |     0 (top_offset)    |
                                       +-----------------------+
                                       | ptr to typeinfo for D |
                          +----------> +-----------------------+
    d --> +----------+    |            |         B::w()        |
          |  vtable  |----+            +-----------------------+
          +----------+                 |         D::y()        |
          |     b    |                 +-----------------------+
          +----------+                 |   12 (vbase_offset)   |
          |  vtable  |---------+       +-----------------------+
          +----------+         |       |    -8 (top_offset)    |
          |     c    |         |       +-----------------------+
          +----------+         |       | ptr to typeinfo for D |
          |     d    |         +-----> +-----------------------+
          +----------+                 |         C::x()        |
          |     a    |                 +-----------------------+
          +----------+
    
  • 相关阅读:
    golang删除数组某个元素
    golang用通道实现信号量,控制并发个数
    什么是ScaleIO中的forwards rebuild和backwards rebuild?
    SQL Server中的database checkpoint
    如何将thick provision lazy zeroed的VMDK文件转换为thick provision eager zeroed?
    LoadTestAgentResultsLateException in VS2010
    SQL Server Instance无法启动了, 因为TempDB所在的分区没有了, 怎么办?
    VMware vCenter中, 如何辩认虚机上Raw Device Mapping过了的一块物理磁盘?
    SQL Server AlwaysOn Setup Step-By-Step Guide
    TPC-E在populate测试Database时需要注意的一些事项
  • 原文地址:https://www.cnblogs.com/biterror/p/7053347.html
Copyright © 2020-2023  润新知