为什么重复的空基存储不与 vtable 指针重叠?
Why doesn't storage for a duplicate empty base overlap with a vtable pointer?
考虑这个例子:
#include <iostream>
int main()
{
struct A {};
struct B : A {};
struct C : A, B {};
std::cout << sizeof(A) << 'n'; // 1
std::cout << sizeof(B) << 'n'; // 1
std::cout << sizeof(C) << 'n'; // 2, because of a duplicate base
struct E : A {virtual ~E() {}};
struct F : A, B {virtual ~F() {}};
std::cout << sizeof(E) << 'n'; // 8, the base overlaps the vtable pointer
std::cout << sizeof(F) << 'n'; // 16, but why?
}
(在导螺杆上运行(
在这里,您可以看到,对于struct E
,空基类(1字节大(使用与vtable指针相同的存储,正如预期的那样。
但对于具有重复空基的struct F
,这种情况不会发生。是什么原因造成的?
我在GCC、Clang和MSVC上得到了同样的结果。以上结果适用于x64,因此sizeof(void *) == 8
。
有趣的是,对于struct G : A, B {void *ptr;};
,GCC和Clang确实执行EBO(大小为8(,但MSVC不执行(大小为16(。
因为编译器在结构A 后添加了一个字节的填充
F{vptr(8(+来自A的0个成员+1个填充(因为A为空(+来自b的0个}=9则编译器添加7个字节的填充以对齐结构体的存储;
E{vptr(8(+A的0个成员}=8无需填充
来自Microsoft
每个数据对象都有一个对齐要求。对于结构要求是其成员中最大的。每个对象都已分配偏移,使得偏移%对准要求==0
https://learn.microsoft.com/en-us/cpp/c-language/storage-and-alignment-of-structures?view=vs-2019年
编辑:
这是我的演示:
int main()
{
C c;
A* a = &c;
B* b = &c;
std::cout << sizeof(A) << " " << a << 'n';
std::cout << sizeof(B) << " " << b << 'n';
std::cout << sizeof(C) << " " << &c << 'n';
E e;
a = &e;
std::cout << sizeof(E) <<" " << &e << " " << a << 'n';
F f;
a = &f;
b = &f;
std::cout << sizeof(F) << " " << &f << " " << a << " " << b << 'n';
}
输出:
1 0000007A45B7FBB4
1 0000007A45B7FBB5
1 0000007A45B7FBB4
8 0000007A45B7FC18 0000007A45B7FC20
16 0000007A45B7FC38 0000007A45B7FC40 0000007A45B7FC41
正如你所看到的&b从不相互重叠,并且在多重继承上具有vptr,每个vptr都有自己的指针值
由VC2019 x64版本编译的说明
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 为什么重复的空基存储不与 vtable 指针重叠?
- 为什么 fdump-class-hierarchy 为虚函数提供了两个指针 int vtable
- 正在读取虚拟函数表 (vtable) 指针?
- C vtable在多个继承中,指向thunk方法的指针
- 我明白为什么,但是虚拟函数/VTable 究竟如何允许通过指针访问正确的函数?
- 从C 中的VTable获取方法指针
- 将VTable类铸造为void指针(C )
- 从派生的指针中调用虚拟功能,而无需支付VTable价格
- c++:vtable是否包含指向非虚拟函数的指针
- 我实际上是在调用 ctor 并在指向对象的指针上初始化 vtable 吗?C++
- 从 Objdump 实用程序检索 vptr(指向虚拟表又名 VTABLE 的指针)
- 指向 D3D11 设备 vtable 的正确指针
- 指向不同地址的 vTable 和函数指针
- 如果类实现多个接口,VTable 的方法指针顺序是什么?
- 在VTable指针和malloc