c++ - Virtual inheritance doesn't break static composition? -
i working last 5 years assumption virtual inheritance breaks static composition.
but discovered, static composition still maintained, there additional information location of correct instance. right?
data layout in non-virtual inheritance:
class point2d { int x_, y_; }; class point3d : public point2d { int z_; };
point2d:
+--------------+ | int x_ | +--------------+ | int y_ | +--------------+
point3d:
+--------------+ --+ | int x_ | | +--------------+ +-- point2d subobject | int y_ | | +--------------+ --+ | int z_ | +--------------+
point3d statically composed of point2d , member of point3d.
under virtual inheritance
implemented offset variable inside object.
class point3d : public virtual point2d { int z_; };
point3d:
+-----------------+ | int z_ | +-----------------+ | point2d* _vbase | --> offset point2d subobject (2 in case) +-----------------+ --+ | int x_ | | +-----------------+ +-- point2d subobject | int y_ | | +-----------------+ --+
accessing point3d* point3d->x_
in context translated (c++ pseudocode):
(static_cast<point2d*>(point3d) + point3d->_vbase)->x_
note there different ways implement virtual inheritance offset pointers inside vtable, 1 way implement virtual inheritance. chose 1 because indirection via vtables require more ascii drawing.
virtual inheritance has no benefit here , expect (as @matthieu noted in comments) compiler optimize class it's internal data layout same in non-virtual inheritance. virtual inheritance beneficial in multiple inheritance (see vertex3d
class below).
how in multiple inheritance?
class vertex : virtual point2d { vertex* next_; }; class vertex3d : public point3d, public vertex { };
vertex:
+-----------------+ | vertex* next_ | +-----------------+ | point2d* _vbase | --> offset of point2d subobject (2 in case) +-----------------+ --+ | int x_ | | +-----------------+ +-- point2d subobject | int y_ | | +-----------------+ --+
vertex3d:
+------------------+ --+ | int z_ | | +------------------+ +-- point3d subobject | point2d* _vbase1 | |--> offset point2d subobject (4 in case) +------------------+ --+ | vertex* next_ | | +------------------+ +-- vertex subobject | point2d* _vbase2 | |--> offset point2d subobject (2 in case) +------------------+ --+ | int x_ | | +------------------+ +-- shared point2d subobject | int y_ | | both point3d , vertex point +------------------+ --+ single copy of point2d
in virtual multiple inheritance both base classes vertex
, point3d
share base point2d
in vertex3d
. non-virtual inherited members layed out usual.
the point of virtual multiple inheritance descendants of point3d
, vertex
share 1 copy of point2d
. without virtual multiple inheritance (= "ordinary" multiple inheritance) both point3d
subobject , vertex
subobject of vertex3d
have own copy of point2d
:
layout of vertex3d
without virtual multiple inheritance:
+------------------+ --+ | int z_ | | +------------------+ +-- point3d subobject --+ | int x_ | | | +------------------+ | +-- point2d subobject | int y_ | | | of point3d +------------------+ --+ --+ | vertex* next_ | | +------------------+ +-- vertex subobject --+ | int x_ | | | +------------------+ | +-- point2d subobject | int y_ | | | of vertex +------------------+ --+ --+
references:
- lippman: inside c++ object model. chapter 3
Comments
Post a Comment