This is simply how pointer arithmetic goes (see
http://www.cplusplus.com/doc/tutorial/pointers/)...
The result of the pointer subtraction is expressed in terms of pointed-to object sizes, not bytes. The addition of an integer to a pointer works equivalently, that way being consistent with indexing. Actually,
p[n] is just another way to write
*(p + n) (but it looks much nicer... :)). If you want a result in bytes, cast the pointers to
char * (
not _TCHAR *, since
_TCHAR may have a size of two bytes) first:
Code:
int diff = reinterpret_cast<char *>(&b[2]) - reinterpret_cast<char *>(&b[1]);
... or simply multiply the result by
sizeof(B).
That's somewhat related to the above: You're indexing an array of
B objects, and that's all the compiler knows at that point. So it ignores the fact that the array actually is comprised of
D objects which are of different size. So it bases its address calculation on the size of
B and the result, although it actually points to memory you own, points to anything but (the start of) a valid oject of
any type. IIRC what's going on here is called
object slicing, and it's definitely evil.
I can envision a haphazard hack to force something like that to work, involving a virtual function by which a given object can return its own concrete size. But due to the variable object size, you can't index such a data structure, so it would rather resemble a linked list than an array, and that's just one of several weird complications such an approach would most certainly provoke. Much better would be to simply take the straightforward and common approach of using an array (or
std::vector) of pointers rather than object instances (like any experienced programmer most certainly would, BTW).