Interesting question. I have an example where a derived class with an extra field is the same size as an empty base class. (This should be a comment but is much too large; please accept one of the other answers, although upvotes are welcome if it's interesting.)
Consider this trivial C++ program:
class A {};
class B : public A {
int m_iInteger;
};
int _tmain(int argc, _TCHAR* argv[])
{
printf("A: %d\r\n", sizeof(A));
printf("B: %d\r\n", sizeof(B));
printf("int: %d\r\n", sizeof(int));
return 0;
}
What would you expect the output to be, if sizeof(int)
is 4? Perhaps something like:
A: 0
B: 4
int: 4
?
My compiler - Embarcadero C++ Builder 2010 - gives the output:
A: 8
B: 8
int: 4
In other words, adding an extra field in the derived class does not make the derived class bigger.
There is some insight into why with the help file topic on the compatibility option Zero-length empty base class.
Usually the size of a class is at least one byte, even if the class
does not define any data members. When you set this option, the
compiler ignores this unused byte for the memory layout and the total
size of any derived classes; empty base classes do not consume space
in derived classes. Default = False
It appears that the size of a class with default compiler settings for this compiler is 8 bytes, not one, and in fact changing this setting for this code example has no effect.
You may also find this article on base class sizes and the above optimization interesting. It discusses why classes must have a size of at least one byte, what the optimization does, and delves into representation of member functions etc too:
Indeed, the standard requires that the size of an object shall never
be zero; it also requires that in a derived object data members of the
base class(es) shall appear before user-declared data members of the
derived class. However, a base class subobject isn’t considered a
complete object. Therefore, it’s possible to remove the base class
subobject from the derived object without violating the rules. In
other words, in the object t, the offset of S and x may overlap...
Please read the article for the full context of that quote.
Derived
can't be smaller thanBase
, if the empty base class rules are used. – James KanzeD
, and still end up withsizeof(D) == sizeof(B)
). But the standard doesn't prevent it; one could imagine an implementation where the size were in some way dependent on the name. (But I feel fairly confident that you'll never actually see such an implementation, and I don't worry about a loss of portability if my code doesn't take this possibility into account.) – James Kanze