具有虚拟指针和继承的 CPP 类大小
cpp class size with virutal pointer and inheritance
class A{
virtual void a();
};
class B : A{
virtual void a();
};
class C{
virtual void a();
};
class E : A, C{
virtual void a();
};
int main(){
std::cout << (sizeof(B)) << "n"; // 4
std::cout << (sizeof(C)) << "n"; // 4
std::cout << (sizeof(E)) << "n"; // 8
}
在 32 位系统中 Linux
为什么 sizeof(B( 和 sizeof(C( 都是 4
对于 C 类,它有一个虚函数,因此在 C 类中隐藏了一个 4 字节的虚拟指针
但为什么B类的大小也是4。我认为它在 B 类中存在两个指针,一个是 B 本身,因为 B 类有一个虚函数,一个是 A 的。
那么E也有同样的问题呢?
任何帮助不胜感激
不,每个使用虚函数的对象中只有一个 vtable 指针,如果虚函数是在类本身中定义的,或者该类派生自另一个使用虚函数的类,则独立地存在。
编译器生成的是一个函数指针表,因此每个类(不是实例/对象(都有自己的。在您的示例中,您有一个用于类 A 的表,一个用于类 B 的表,依此类推。在每个对象/实例中,您都有一个 vtable 指针。此指针仅指向表。如果通过类指针调用虚函数,则间接寻址在 vtable 指针上,而不是在 vtable 本身上。
因此,类的每个实例只保留一个指向此类的 vtable 的 vtable。如您所见,这会导致您编写的每个类的每个实例的大小相同。
在多重继承的情况下,您将获得多个 vtable 指针。这里已经给出了更详细的答案: vtable 和多重继承
顺便说一句:标准并不能保证你有一个 vtable 和一个 vtable 指针,如果结果是我们从语义中期望的,每个编译器都可以做它想做的事。但是,通过 vtable 指针到表中指向函数的指针的双重间接寻址是典型的实现。
对于单一继承,派生类 B 只是在虚拟表中再插入一个条目。 对于多重继承,派生类 E 有 2 个虚拟表指针。
进一步:C++MI(多重继承(的虚拟表布局
相关文章:
- .cpp和.h文件中的模板专用化声明
- 继承函数的重载解析
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运算符继承和 cpp 核心准则 c.128 的问题
- 具有虚拟指针和继承的 CPP 类大小
- CPP 继承虚拟方法解析顺序
- CPP继承有些误解
- "Attribute is protected within this context"继承和 .h 和.cpp文件
- C++继承 - 覆盖功能,包括使用 "::" s、.h 文件和.cpp文件
- 朋友功能和继承在CPP中
- cpp迭代器继承
- Eclipse报告了有效cpp继承的错误
- CPP 多重继承意外调用 CTOR
- C++ cpp 文件中继承的功能
- .cpp.模板类继承不起作用
- 不能将兄弟方法与虚拟继承 cpp 一起使用
- 继承.h和.cpp文件中的构造函数
- 是否有任何cpp函数或对象(不包括从c继承的)不是线程安全的,即使每个线程对自己的数据进行操作
- CPP继承问题
- cpp 套接字,继承错误