2009-05-11 3 views
0

В C++ проблема проста.C++ RTTI Inheritance приводит к увеличению размера класса

У меня есть 2 класса, один содержит другой как часть его реализации.

struct A 
{ 
    void do_something() 
    { 
    }; 
}; 

struct B 
{ 
    A obj_A; 
    void hello_world() 
    { 
    }; 
}; 

Теперь проблема заключается в том, что структура В один байт больше, если А является частью B, когда я делать SizeOf (B) и объект типа B. А 100% только будет включать в себя только невиртуальном членов (нет необходимости в виртуальной таблице), и нет необходимости в проверке типа. Есть ли способ (например, директива компилятора) полностью удалить ненужный байт из B, но все же получить доступ к функции члена A через B?

Я могу только предположить, что дополнительный байт - это компилятор, добавленный char * к имени A «A», но любые другие идеи могут быть полезны.

+0

Если ваш компилятор G ++, попробуйте отключение RTTI путем компиляции с помощью 'g ++ -fno-rtti'. Если проблема не устранена, укажите полный исходный файл C++, который обнаруживает проблему, и я увижу, какой размер моего компилятора дает. – pts

+1

FWIW: Я попытался скомпилировать ваш код с g ++ (версия 4.2.4) с и без члена obj_A, с включенным RTTI и без него, и каждый раз, когда я получил sizeof (B) == 1. Таким образом, кажется, что некоторая информация отсутствует от вашего вопроса. –

ответ

2

Вы, к сожалению, не упомянули компиляторы.

В любом случае, в коде, который вы публикуете, класс A является кандидатом на «Оптимизацию пустого базового класса». Что является частью стандарта C++, в котором говорится, что базовый класс без переменных-членов можно оптимизировать, чтобы не принимать никаких байтов.

B должен по стандарту C++ занимать пространство, так как он содержит хотя бы один элемент (а именно obj_A).

Вы можете получить доступ к функции-члену A непосредственно изнутри B, вызвав do_something(). Магии не требуется.

+0

Действительно ли класс А считается базовым классом? –

+0

Да, это также класс листьев –

+0

Это может быть базовый класс, но не базовый класс B. – Ari

4

SizeOf (A) не может быть 0, потому что каждая часть объекта должна быть «adressable» (то есть должен иметь другой адрес, когда мы используем оператор &)

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" 
} 
+0

+1 Правильно. Кроме того, каждый новый класс должен возвращать другой адрес, чтобы использование удаления работало должным образом. То, что классы причин в C++ не могут иметь размер = 0. Кроме того, есть аспекты заполнения, которые компилятор может добавить, чтобы объект совпадал с границей памяти-слова. – Abhay

Смежные вопросы