zoukankan      html  css  js  c++  java
  • 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    |                 +-----------------------+
          +----------+
    
  • 相关阅读:
    安裝Node.js
    es match、match_phrase、query_string和term的区别
    ES系列十、ES常用查询API
    ElasticSearch 入门总结
    起立,老师好
    像哆啦A梦懂大雄一样懂客户,我们也会拥有百宝箱
    阿里云居然在偷偷发福利!
    别人家的公司又来了,这次竟然开起了演唱会
    听说国家博物馆收藏了一行代码 ???
    我还是那个我,为啥就被老板区别对待了呢?
  • 原文地址:https://www.cnblogs.com/biterror/p/7053347.html
Copyright © 2011-2022 走看看