Can “multiple interface inheritance” replace “virtual inheritance”?


Obviously this is C#’s approach, replacing “virtual inheritance” with “multiple interface inheritance”.
Are there any drawbacks other than that no data member is allowed in interfaces?
Yes and No. There are cons and pros with “multiple interface inheritance”, and they roughly cancel out.

struct CMultiBase
{
	virtual void f() = 0;
};
struct CMultiBase1: CMultiBase
{
	virtual void f1() = 0;
};

struct CMultiBase2: CMultiBase
{
	virtual void f2() = 0;
};

struct CMultiSub: CMultiBase1, CMultiBase2
{
	void f()  { }
	void f1() { }
	void f2() { }
};
void TestMulti()
{
	CMultiSub s;
	CMultiBase1 *p1 = &s;
	CMultiBase2 *p2 = &s;
	unsigned int * pRawDword1 = reinterpret_cast<unsigned int*>(p1);
	unsigned int * pRawDword2 = reinterpret_cast<unsigned int*>(p2);
	cout << "first entry in CMultiBase1's vtable is " << hex << *(int*)(*pRawDword1) << endl;
		//This is CMultiSub::f as seen from watch window (expand p1 then CMultiBase1)
	cout << "first entry in CMultiBase2's vtable is " << hex << *(int*)(*pRawDword2) << endl;
		//This is [thunk]:CMultiSub::f as seen from watch window
}

From the output above, we can see:
1. CMultiSub’s vtable has two entries for f(). There is only one f() in case of ‘virtual inheritance’.
2. There are only 2 vtable pointers in CMultiSub (located at pRawDword1 and pRawDword1), while there are three vtable pointers in case of ‘virtual inheritance’: one extra for virtual base.
Summary: “multiple interface inheritance” takes less space by taking out one vfptr, and takes more space by duplicated entries in vtable.
So the final answer is yes. No wonder both C# and Java took this approach.

Advertisements
Comments are closed.
%d bloggers like this: