The below code is of multiple inheritance where every class has one member variable, one normal function and one virtual function.
class basec
{
int x;
public:
basec()
{
x = 0;
}
void print()
{}
virtual void xyz()
{}
};
class derivedc: public virtual basec
{
int dc;
public:
derivedc()
{
dc = 0;
}
virtual void xyzdc()
{}
};
class derivedd: public virtual basec
{
int dd;
public:
derivedd()
{
dd = 0;
}
virtual void xyzdd()
{}
};
class child: public derivedc, public derivedd
{
char de;
public:
child()
{
de = '4';
}
virtual void xyzde()
{}
};
main(int argc, char **argv)
{
basec bobj, bobjc;
derivedc dcobj;
derivedd ddobj;
child deobj;
std::cout << "C " << sizeof(basec) << endl;
std::cout << "D " << sizeof(derivedc) << endl;
std::cout << "E " << sizeof(derivedd) << endl;
std::cout << "F " << sizeof(child) << endl;
return(0);
}
Output of the program is as follows:
main()
C 8
D 16
E 16
F 28
Seeing each of the object in gdb I see below:
(gdb) p/x bobj
$1 = {_vptr.basec = 0x8048c80, x = 0x0}
(gdb) p/x dcobj
$3 = {<basec> = {_vptr.basec = 0x8048c5c, x = 0x0}, _vptr.derivedc = 0x8048c4c, dc = 0x0}
(gdb) p/x ddobj
$4 = {<basec> = {_vptr.basec = 0x8048c1c, x = 0x0}, _vptr.derivedd = 0x8048c0c, dd = 0x0}
(gdb) p/x deobj
$5 = {<derivedc> = {<basec> = {_vptr.basec = 0x8048b90, x = 0x0}, _vptr.derivedc = 0x8048b6c, dc = 0x0}, <derivedd> = {_vptr.derivedd = 0x8048b80, dd = 0x0}, de = 0x34}
We see that in the base class "basec" and in each of the virtually derived classes "derivedc" and "derivedd" objects a vptr is added for their vtables.
Question is why the child class inspite of having a virtual function does not have its own vtable and why no vptr of its own in its object? In which class's vtable will the virtual function of child class appear?
override
methods anywhere in your example. What happens if you name each of the virtual functions to justxyz
? - Tim Randallchild::xyzde()
in thederivedc
vtable in child see "vtable for child" - gcc.godbolt.org/z/d2VWza. If you changechild
toclass child: public virtual derivedc, public virtual derivedd
you get three separate tables. gcc.godbolt.org/z/wCbmWb. An if you remove allvirtual
inheritance you getbasec
copied as expected - gcc.godbolt.org/z/8wxPGA. - Mihaylvtable for child:... .quad derivedc::xyzdc() .quad child::xyzde() .... .quad typeinfo for child .quad derivedd::xyzdd() ... .quad typeinfo for child .quad basec::xyz()
- Mihayl