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 继承导致类大小增加的主要内容,如果未能解决你的问题,请参考以下文章

减小Delphi2010程序的尺寸(关闭RTTI反射机制)

在 C++ 中增加堆栈大小

C++类的大小计算汇总

使用基类指针查找派生类对象的大小

C++ Primer 5th笔记(chap 19 特殊工具与技术)使用 RTTI

单独继承的派生类的大小