sizeof
will always return the static size of your object. Notice that in your example it will coincide with the true object size, as there is no polymorphism; when you do
A a = B();
a
is of type A
- you just happened to initialize a new A
object with a new B
object, which results in slicing (a
gets initialized with the fields of B()
that are common with A
).
A better example would be:
B b;
A *a = &b;
In this case, *a
will indeed be of dynamic type B
, but sizeof(*a)
will still return sizeof(A)
, not sizeof(B)
.
There are several ways to obtain the dynamic size of an object:
- save it into a field at construction time;
- in theory, you could define a virtual method that does
return sizeof(*this);
and redefine it in all derived classes.
That being said, this last method won't be particularly useful, as doing memcpy
of non-trivial types such as polymorphic classes is undefined behavior (and so even the first method as well, as I imagine that you'll want to do this with polymorphic types).
The common approach to the problem of copying polymorphic classes is to accept the fact that they'll have to live in the heap and define clone()
method that does virtual A * clone() {return new B(*this);}
(where B
is the derived class) in each derived class, and invoke clone()
whenever you need a copy.
Mind you, there are subtler tricks you can pull; once I had a class hierarchy which had a virtual method dispatching to the placement new
for each derived class and one for the destructor, but you really have to know what you are doing (in my case I was invoking them over a union
containing an instance for each derived class, so size and alignment was not a problem).