how to determine the size of virtual base class and derived classes from it?

前端 未结 4 1056
梦谈多话
梦谈多话 2021-01-05 12:53
#include 
using namespace std;

class base1{};
class base2{virtual void show(){}};

class test1{    };
class test2{virtual void show(){}};

class der         


        
相关标签:
4条回答
  • 2021-01-05 13:26

    how to determine the size of virtual base class and derived classes from it??

    Use sizeof().

    0 讨论(0)
  • 2021-01-05 13:39

    An Empty class inheriting a base class in virtual (access specifier ) mode (ex.virtual public) has size of 8 while if is non-empty it would have a size of 16.

    0 讨论(0)
  • 2021-01-05 13:42

    My old paper "C++: Under the Hood" explains the Microsoft C++ implementation of virtual base classes. http://www.openrce.org/articles/files/jangrayhood.pdf

    And you can compile with cl /d1reportAllClassLayout to get a text report of class memory layouts.

    Happy hacking!

    0 讨论(0)
  • 2021-01-05 13:43

    The reason that sizeof(base1) and sizeof(test1) are 1 is solely to prevent a most-derived object from having size 0. That's all the standard forbids. Base class sub-objects are allowed to have size 0 (that is, allowed to occupy no bytes), and hence adding base1 as a base doesn't necessarily have to add anything to the size of the class.

    The optimization your compiler has made, not allocating any bytes for a base-class sub-object whose type is an empty class, is called the "empty base class optimization". It's not required by the standard that the implementation apply it, but an implementation that didn't might not be considered fit for serious work.

    I think derv22 is somewhat similar - if the compiler is capable of dealing with two virtual base classes using a single extra pointer, then it's entitled to do so. Hence, you might only have to "pay" once, rather then "paying" per virtual base. That could depend on the compiler and on the exact relationships between the classes, though, I've never surveyed different implementations to see if and when they're forced to add multiple pointers worth of overhead.

    Apparently derv222 has done it, though, at least for your compiler. I suppose that this is because the base2 and test2 base class sub-objects need separate vtable pointers. Probably not that surprising if you consider what happens when you static_cast a derv222* as a pointer to one base or the other - both results need to be capable of having show() called on them, and calling different functions (albeit the show functions currently do nothing). I'm not sure whether it would be possible for another compiler to implement this inheritance in 8 bytes -- for one thing inheritance doesn't have to be implemented using vtables.

    0 讨论(0)
提交回复
热议问题