似乎每个类都有一个虚拟 ptr 就足够了,即使一个类派生自两个基类。
例如
#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;
}
此输出为
16
16
32
这是有道理的,因为sizeof B = sizeof A + sizeof C
.但是,这似乎有点低效。为什么B
需要分配 2 个虚拟指针?为什么不只分配一个引用 B 自己的虚拟表?然后sizeof B
将24
.谢谢!
因为你可以做
B b{};
C* pc = &b;
pc->cFunc();
pc
必须指向看起来像C
的东西 - 包括从适合C
的虚拟指针开始。
B
和A
可以共享同一个虚拟指针,因为编译器可以使B
的虚拟表以与A
的虚拟表相同的方式开始(然后在末尾有一些额外的东西)。但它不能同时为A
和C
做到这一点。B
的虚拟表不能以与A
相同的方式开始,也不能以与C
相同的方式开始。那是不可能的。