Подтвердить что ты не робот

Структура объекта С++ в памяти Vs a Struct

Если у меня есть класс следующим образом

   class Example_Class 
   {
       private:
         int x; 
         int y; 
       public: 
         Example_Class() 
         { 
             x = 8;
             y = 9;
         }
       ~Example_Class() 
       { } 
   };

И следующая структура

struct
{
   int x;
   int y;
} example_struct;

Является ли структура в памяти example_struct похожей на структуру в Example_Class

например, если я делаю следующее

struct example_struct foo_struct;
Example_Class foo_class = Example_Class();

memcpy(&foo_struct, &foo_class, sizeof(foo_struct));

будет foo_struct.x = 8 и foo_struct.y = 9 (т.е. те же значения, что и значения x, y в foo_class)?

Я спрашиваю, есть ли у меня библиотека С++ (не хочу ее менять), которая использует объект с кодом C, и я хочу использовать структуру для представления объекта, идущего из библиотеки С++. Меня интересуют только атрибуты объекта.

Я знаю, что идеальная ситуация заключалась бы в том, чтобы обернуть Example_class вокруг общей структуры между кодом C и С++, но не будет легко изменить используемую библиотеку С++.

4b9b3361

Ответ 1

Стандарт С++ гарантирует, что макеты памяти C struct и С++ class (или struct - то же самое) будут одинаковыми при условии, что С++ class/struct соответствует критериям of POD ( "Обычные старые данные" ). Итак, что означает POD?

Класс или структура - это POD, если:

  • Все члены данных являются общедоступными, а сами POD или базовые типы (но не ссылочные или указательные), или массивы таких
  • У него нет пользовательских конструкторов, операторов присваивания или деструкторов
  • У него нет виртуальных функций
  • Он не имеет базовых классов

Об одном разрешении "С++ - isms" допускаются не виртуальные функции-члены, статические члены и функции-члены.

Поскольку ваш класс имеет как конструктор, так и деструктор, он формально говорит не о типе POD, поэтому гарантия не выполняется. (Хотя, как отмечали другие, на практике два макета, вероятно, будут одинаковыми на любом компиляторе, который вы пытаетесь, пока нет виртуальных функций).

Подробнее см. раздел [26.7] С++ FAQ Lite.

Ответ 2

Является ли структура в памяти example_struct похожей на структуру в Example_Class

Поведение не гарантируется и зависит от компилятора.

Сказав это, ответ "да, на моей машине" при условии, что Example_Class не содержит виртуального метода (и не наследует от базового класса).

Ответ 3

В случае, описанном вами, ответ "вероятно, да". Однако, если класс имеет любые виртуальные функции (включая виртуальный деструктор, который может быть унаследован от базового класса) или использует множественное наследование, тогда макет класса может быть другим.

Ответ 4

Чтобы добавить к словам других людей (например, специфические для компилятора, скорее всего, будут работать, пока у вас нет виртуальных функций):

Я бы очень хотел предложить static assert (проверка времени компиляции), что sizeof (Example_class) == sizeof (example_struct), если вы это делаете. См. BOOST_STATIC_ASSERT или эквивалентную конструкцию, специфичную для компилятора или пользовательскую. Это хорошая защита первой линии, если кто-то (или что-то вроде изменения компилятора) изменяет класс, чтобы аннулировать совпадение. Если вам нужна дополнительная проверка, вы также можете проверить время выполнения, что смещения для членов совпадают, что (вместе с утверждением статического размера) гарантирует правильность.

Ответ 5

Классы и структуры в С++ эквивалентны, за исключением того, что все члены структуры являются общедоступными по умолчанию (по умолчанию члены класса являются закрытыми). Это гарантирует, что компиляция устаревшего кода C в компиляторе С++ будет работать должным образом.

Нет ничего, что помешало бы вам использовать все фантастические возможности С++ в структуре:

struct ReallyAClass
{
    ReallyAClass();
    virtual !ReallAClass();

    /// etc etc etc
};

Ответ 6

Почему бы явным образом не назначать членам класса структуре, когда вы хотите передать данные на C? Таким образом, вы знаете, что ваш код будет работать где угодно.

Ответ 7

В первые дни компиляторов С++ были примеры, когда компилятор сначала меняет ключевые слова struct с классом, а затем компилирует. Так много о сходствах.

Отличия происходят от наследования классов и, особенно, от виртуальных функций. Если класс содержит виртуальные функции, то он должен иметь указатель на тип дескриптора в начале его компоновки. Кроме того, если класс B наследуется от класса A, сначала выполняется макет класса A, а затем собственный макет класса B.

Итак, точный ответ на ваш вопрос о простоте экземпляра класса для экземпляра структуры: зависит от содержания класса. Для конкретного класса, который имеет методы (конструктор и не виртуальный деструктор), макет, вероятно, будет таким же. Если деструктор объявлен виртуальным, макет определенно станет другим между структурой и классом.

Вот статья, в которой показано, что для перехода от структур C к классам С++ не так уж и нужно: Урок 1 - От структуры к классу

И вот статья, в которой объясняется, как таблица виртуальных функций вводится классам, имеющим виртуальные функции: Урок 4 - Полиморфизм

Ответ 8

Вероятно, вы просто получаете класс из структуры, как публично, так и конфиденциально. Тогда кастинг будет корректно разрешаться в коде С++.