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