It seems that it's sufficient to have a virtual ptr per class even when a class is derived from two base classes.
For example,
#include <iostream>
class A{
public:
void* ptr;
virtual void printNonOverride() {
std::cout << "no override" << std::endl;
}
virtual void print() {
std::cout << "hello world!" << std::endl;
}
};
class C {
public:
double c;
virtual void cFunc() {
std::cout << "C";
}
};
class B : public A , public C {
};
int main() {
A a{};
std::cout << sizeof a << std::endl;
C c{};
std::cout << sizeof c << std::endl;
B b{};
std::cout << sizeof b << std::endl;
}
The output for this is
16
16
32
which makes sense because sizeof B = sizeof A sizeof C
. However, this seems a little bit inefficient. Why does B
need to allocate 2 virtual pointers? Why not just allocate one that refers to B's own virtual tables? Then the sizeof B
will be 24
. Thank you!
CodePudding user response:
Because you can do
B b{};
C* pc = &b;
pc->cFunc();
and pc
has to point to something that looks like a C
- including starting with a virtual pointer suitable for a C
.
B
and A
can share the same virtual pointer, because the compiler can make it so that B
's virtual table begins the same way as A
's virtual table (and then has some extra stuff at the end). But it can't do this for both A
and C
at the same time. B
's virtual table can't begin the same way as A
's and begin the same way as C
's. That's not possible.