There is an object who's members I need to find the size of. I am specifically asking for the object's size without it's v-table considered. Also, I cannot modify it, so I cannot take advantage of this answer.
Is there a provision for this in C++, beyond summing a hard-coded sizeof
for each member?
I am aware that v-tables are not mandated by C++. I am also aware that anything I do with this information will be widely considered "bad form". This question is simply asking if it's possible, not endorsing the behavior.
It has come to my attention that I need to clarify this question. What I wanted to learn with this question was how to cast a parent to a child. That is, I wanted to preserve the child's v-table, but copy the parent's member variables: https://stackoverflow.com/a/31454039/2642059
The accepted answer does provide me the information I needed to do this. But, in-spite of behavior that I consider endemic to the worst of http://stackoverflow.com curiousguy points out a shortcoming of the accepted answer.
The extension from the accepted answer to multiple inheritance is patently obvious, but it is valid that the answer should include it. As a stopgap I've added a live example of how to deal with multiple inheritance: http://ideone.com/1QOrMz I will request that user2596732 updates his answer or I will add a supplementary answer to the question on how to deal with multiple inheritance.
In order to discover the layout of a polymorphic object, you can compare pointers to member objects; the simple demonstration program "draws" the layout of an object with symbols:
*
indicates part of the object that do not belong to any member subobject or base class subobjectThere is a symbol for each byte (a
char
is a byte by definition).The vptr(s) must be in the "empty" space, the space not allocated for data members.
Type definitions are:
Output is:
See https://ideone.com/g5SZwk
Because we know the compiler is using vptrs, the locations of the vptrs are obvious in these "drawings".
About inheritance in C++
Non-virtual inheritance
When virtual inheritance is not used, the base class subobjects inheritance graph is always a tree rooted in the most derived class, even when the subtyping graph is not a tree:
The subtyping graph is:
The subobject graph is:
This is crucial effect of non-virtual inheritance: the graphs don't always match. If you don't understand that you don't understand non-virtual inheritance!
This implies that conversions from
Bottom*
toRepeated*
are ambiguous.In this example:
Bottom::f()
overrides bothLeft::Repeated::f()
andRight::Repeated::f()
at the same time.Left::Repeated::g()
is overridden byLeft::g()
Right::Repeated::g()
is overridden byRight::g()
Here the lookup of the name
g
inBottom
would fail with an ambiguity, so it would be an error to use an unqualifiedg
inBottom
.Virtual inheritance
When virtual inheritance is used, the base class subobjects inheritance is an acyclic directed graph with the most derived class as a unique terminal:
Here all other
f()
declarations overrideUnique::f()
.Here the subobject graph matches the subtype graph:
Nope.
sizeof(Class) only includes a VTable pointer.
So for this example,
should give you the correct answer. 8 16 20