Re: Virtual function and multiple inheritance



* George "the mysterious BOT":
(this question is posted to vc.language newsgroup)

Hello everyone,


In the following multiple inheritance sample code, I have tested in class Derived, there are two __vfptr, pointing to the virtual function table for Foo and Goo repectively -- i.e. 8 bytes, 2 pointer on 32-bit machine.

My questions,

1. Why two __vfptr is needed? Why not just one?
2. class Derived has its own virtual method func2, why it does not have its own virtual function table pointer?

[Code]
class Foo {
public:
virtual int func() {return 1;};
};

class Goo {
public:
virtual int func() {return 2;};
};

class Derived: Foo, Goo {
public:
virtual int func2() {return 3;};
int increase() {return -1;};
int decrease() {return -2;};
};

int main()
{
Derived d;
int size;

size = sizeof (d); // size is 8, two __vfptr?

return 0;
}
[/Code]


Consider

Derived* pD = &d;
Foo* pF = pD;
Goo* pG = pD;

Here pF is a pointer to an object with the same memory layout as a Foo (it is, typewise, a Foo) and pG is a pointer to an object with the same memory layout as a Goo (ditto).

That implies that a Derived /contains/ a Foo and a Goo object; in the standard they're called "sub-objects".

However, in a vtable-based implementation the Foo sub-object's vtable pointer does not necessarily point to the Foo vtable, but in the general case to a copy with the function pointers corresponding to overrides in Derived, replaced with pointers to Derived's overrides. And ditto for the Goo sub-object.

Derived does not technically need a separate vtable and vtable pointer because it can just extend (the copy of) the Foo or Goo vtable.

How that is done is an implementation detail.

A consequence of the above is that multiple inheritance can have an O(n^2) memory cost where n is the total number of class derivations overriding base virtual functions. I haven't thought more deeply about it but I don't think it can be worse. Some programmers erronously think that this strongly contra-indicates using multiple inheritance; however, relative to usual memory consumption for any program (even "Hello, world!") the memory cost is in practice vanishingly small.


Cheers, & hth.,

- Alf


PS: Thank you for not multi-posting the above article, if you've finally licked that problem.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
.



Relevant Pages

  • Re: About C++ memory management
    ... int * ptr = new int; ... delete ptr; ... But if I copy this pointer like below should I also delete copied ... Foo ...
    (microsoft.public.vc.language)
  • Re: would C be easier to read if...
    ... That indicates that it's a pointer to a function. ... int *a a is pointer to int ... In my case a type declaration that reads linearly from left to right would ... Let's say we have a regular int identifier named "foo". ...
    (comp.lang.c)
  • Re: help with left-right cdecl rule
    ... This "const int * foo" also makes sense, foo is a pointer to a const ...
    (comp.lang.c)
  • Re: Clarification: strtof wont work
    ... > Now, what you referred to as pointer arithmetic,.... ... void foo(int i) ... of the value in j, altering the value of i, will not alter j. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Virtual function and multiple inheritance
    ... method in Derived which is not in Foo and Goo. ... virtual int myFunc() ... I'll make a guess that these two vtables are specific for Derived. ...
    (microsoft.public.vc.language)