understanding vptr in multiple inheritance?

后端 未结 5 2034
暗喜
暗喜 2021-01-30 11:59

I am trying to make sense of the statement in book effective c++. Following is the inheritance diagram for multiple inheritance.

5条回答
  •  一向
    一向 (楼主)
    2021-01-30 12:37

    If a class has virtual members, one need to way to find their address. Those are collected in a constant table (the vtbl) whose address is stored in an hidden field for each object (vptr). A call to a virtual member is essentially:

    obj->_vptr[member_idx](obj, params...);
    

    A derived class which add virtual members to his base class also need a place for them. Thus a new vtbl and a new vptr for them. A call to an inherited virtual member is still

    obj->_vptr[member_idx](obj, params...);
    

    and a call to new virtual member is:

    obj->_vptr2[member_idx](obj, params...);
    

    If the base is not virtual, one can arrange for the second vtbl to be put immediately after the first one, effectively increasing the size of the vtbl. And the _vptr2 is no more needed. A call to a new virtual member is thus:

    obj->_vptr[member_idx+num_inherited_members](obj, params...);
    

    In the case of (non virtual) multiple inheritance, one inherit two vtbl and two vptr. They can't be merged, and calls must pay attention to add an offset to the object (in order for the inherited data members to be found at the correct place). Calls to the first base class members will be

    obj->_vptr_base1[member_idx](obj, params...);
    

    and for the second

    obj->_vptr_base2[member_idx](obj+offset, params...);
    

    New virtual members can again either be put in a new vtbl, or appended to the vtbl of the first base (so that no offsets are added in future calls).

    If a base is virtual, one can not append the new vtbl to the inherited one as it could leads to conflicts (in the example you gave, if both B and C append their virtual functions, how D be able to build its version?).

    Thus, A needs a vtbl. B and C need a vtbl and it can't be appended to A's one because A is a virtual base of both. D needs a vtbl but it can be appended to B one as B is not a virtual base class of D.

提交回复
热议问题