Схема памяти множественного наследования C++ с «пустыми классами»

Я знаю, что структура памяти множественного наследования не определена, поэтому мне не следует полагаться на нее. Однако могу ли я полагаться на него в особом случае. То есть класс имеет только один «настоящий» суперкласс. Все остальные являются «пустыми классами», то есть классами, у которых нет ни полей, ни виртуальных методов (, т. е. они имеют только не -виртуальные методы ). В этом случае эти дополнительные классы не должны ничего добавлять к структуре памяти класса. (Точнее, в формулировке C++11 класс имеет стандартный -макет)

Могу ли я сделать вывод, что все суперклассы не будут иметь смещения? Например.:

#include <iostream>

class X{

    int a;
    int b;
};

class I{};

class J{};

class Y : public I, public X,  public J{};

int main(){

    Y* y = new Y();
    X* x = y;
    I* i = y;
    J* j = y;

    std::cout << sizeof(Y) << std::endl 
                  << y << std::endl 
                  << x << std::endl 
                  << i << std::endl 
                  << j << std::endl;
}

Здесь Y— это класс, а X— единственный реальный базовый класс. Вывод программы (при компиляции на Linux с g++4.6 )выглядит следующим образом:

8

0x233f010

0x233f010

0x233f010

0x233f010

Как я понял, регулировки указателя нет. Но является ли эта реализация специфичной или я могу на нее положиться. То есть, если я получаю объект типаI(и я знаю, что существуют только эти классы ), могу ли я использовать reinterpret_cast, чтобы привести его к X?

Я надеюсь, что смогу на это положиться, потому что в спецификации сказано, что размер объекта должен быть не менее байта. Поэтому компилятор не может выбрать другой макет. Если бы Iи Jрасполагались позади членов X,тогда их размер будет равен нулю (, потому что у них нет членов ). Поэтому единственный разумный выбор — выровнять все суперклассы без смещения.

Я прав, или я играю с огнем, если использую здесь переинтерпретировать _с Iна X?

8
задан Rakib 5 August 2014 в 11:22
поделиться