C++ RTTI 继承导致类大小增加
Posted
技术标签:
【中文标题】C++ RTTI 继承导致类大小增加【英文标题】:C++ RTTI Inheritance causes class size to increase 【发布时间】:2009-05-11 21:59:05 【问题描述】:在 C++ 中,问题很简单。
我有 2 个类,其中一个包含另一个作为其实现的一部分。
struct A
void do_something()
;
;
struct B
A obj_A;
void hello_world()
;
;
现在的问题是,当我执行 sizeof(B) 和 B 类型的对象时,如果 A 是 B 的一部分,则结构 B 会大一个字节。A 100% 只会包含非虚拟成员(没有虚拟需要表),并且不需要进行 typeid 检查。有没有办法(比如编译器指令)从 B 中完全删除不需要的字节,但仍然通过 B 访问 A 的成员函数?
我只能假设额外的字节是编译器将 char* 添加到 A 的名称“A”,但任何其他想法都会有所帮助。
【问题讨论】:
如果您的编译器是 g++,请尝试通过使用g++ -fno-rtti
编译来禁用 RTTI。如果问题仍然存在,请提供一个完整的 C++ 源文件以显示该问题,我将查看我的编译器产生的大小。
FWIW:我尝试使用 g++(版本 4.2.4)编译您的代码,使用和不使用 obj_A 成员,启用和不启用 RTTI,每次我得到 sizeof(B) == 1。所以您的问题似乎缺少一些信息。
【参考方案1】:
sizeof(A) 不能为 0,因为对象的每个部分都应该是“可寻址的”(即当我们使用运算符 & 时应该有不同的地址)
struct A
;
struct B
A m_a1;
A m_a2;
;
void test()
B b;
A* pa1 = &b.m_a1;
A* pa2 = &b.m_a2;
// "pa1" need to be different from "pa2"
【讨论】:
+1 没错。此外,每个新的类都应该返回一个不同的地址,这样删除的使用才能正常工作。这就是 C++ 中的类不能具有 size = 0 的原因。除此之外,编译器可能会添加填充以使对象与内存字边界对齐。【参考方案2】:不幸的是,你没有提到编译器。
无论如何,在您发布的代码中,A 类是“空基类优化”的候选者。这是 C++ 标准的一部分,它说可以优化没有成员变量的基类以不占用字节。
B 必须按 C++ 标准占用空间,因为它包含至少一个成员(即 obj_A)。
您可以通过调用 do_something() 直接从 B 中访问 A 的成员函数。不需要魔法。
【讨论】:
A 类真的算是基类吗? 是的,它也是一个叶子类 可能是基类,但不是B的基类。以上是关于C++ RTTI 继承导致类大小增加的主要内容,如果未能解决你的问题,请参考以下文章