Re: About the address offset when assign address of a derived class to a Base class pointer.
junyangzou <zoujyjs@gmail.com> wrote in
news:0a0abbb0-1789-425e-b3e0-9e123ac10364@googlegroups.com:
On Thursday, August 29, 2013 11:27:34 AM UTC+8, Tobias M?ller wrote:
junyangzou <zoujyjs@gmail.com> wrote:
Say we have two base class Base1, Base2 and a Derived : public
Base1, p
ublic Base2.
When we assign the address of a Derived Object to a Base2 Pointer.
The
address need to be adjust to the beginning of the Base2:
Base2 *pBase2;
Derived d;
pBase2 = &d;
In my machine, the value of pBase2 and &d is 0079FAB0 0079FAB8
respectively, indicating that sizeof( Base1 ) is 8 bytes.
But when and where is the offset added? This can not be done in
compili
ng
time. Because though the example above is quite straightforward.
Some
times we may write code like:
pBase2 = Factory.get();
We known the real type of the returned object only in rumtime. So
anyon
e
can explain when and where is the offset added? Thanks!
The "real" type of the object actually doesn't matter. What matters
is th
e
(statically known) type of the return value of Factory.get(). This
type h
as
to be a common base class of all possible "real" types and the
pointer
adjustment from the "real" type to that common base type happens
_inside_
the Factory.get() method, where the "real" type is statically known.
Tobi
This make sense. So if the Factory method returns an pointer to
Derived( Derived* ) in which the real object is an instance of a
derived class from Derived, say Derived2. The pointer may be( if
needed ) offset twice?
Yes, if there is again multiple derivation involved. E.g.
class Base1 {...};
class Base2 {...};
class Base3 {...};
class Derived1: public Base1, public Base2 {...};
class Derived2: public Base3, public Derived1 {...};
if we now have:
Derived2* x = new Derived2();
Derived1* y = x;
Base2* z = y;
then a typical compiler would translate this into something approximately
like this (space optimizations might change this a bit):
// pseudocode:
x = ...
y = x + sizeof(Base3);
z = y + sizeof(Base1);
Note that after the adjustment has been done, the rest of the code
working with the base class pointer does not have any a priori knowledge
that the complete object is Derived2. If this becomes important, one must
add relevant virtual functions to classes so that all the subobjects
would have vtable pointers where the code can dig up this information at
run-time, for example when processing things like
Derived2* w = dynamic_cast<Derived2*>(z);
or
delete z;