LINUX.ORG.RU

Наследование структур в C++

 ,


0

6

Как известно, в C++ структуры можно наследовать.

struct A {
    int a, b;
};

struct B: A {
    int c, d;
};

struct C {
    int a, b;
    int c, d;
};

Вопрос: будет ли структура B чем-то отличаться во внутреннем представлении от C?

Допустимо ли использовать наследование структур для описания вещей, у которых важно внутреннее представление (оно не должно зависеть от версии компилятора, типа процессора, ОС и т. д.)? Например, данных, которые уйдут по сети или в файл (разумеется, добавить к описанию всех структур __attribute__((packed)) в таком случае)?

Это всё (наследование структур, возможность добавлять структурам конструкторы и методы) лишь синтаксический сахар и пока я не добавлю виртуальных методов (которые вызовут появления в структуре скрытого поля с указателем на vtable) внутреннее представление структуры будет полностью предсказуемо?

★★★★★

Последнее исправление: KivApple (всего исправлений: 1)

B — не POD, точнее, не standard layout. Для таких структур нет гарантии, что структуры с одинаковыми полями в начале будут иметь одинаковое представление.

const86 ★★★★★
()

POD типы

anonymous
()
Ответ на: комментарий от const86

Не верно.

Так будет только если появится виртуальный метод.

anonymous
()

нет. нет(нет). почти: пока структура остаётся pod-типом (определение в разных версиях стандарта разное) представление предсказуемо в том смысле, что его можно копировать с помощью memcpy и сравнивать с помощью memcmp

anonymous
()

Это всё (наследование структур, возможность добавлять структурам конструкторы и методы) лишь синтаксический сахар

Если отнаследовать от POD и добавить кучку невиртуальных методов, то будет всё ещё standard layout (см. мой предыдущий пост). Если в генеалогическом дереве есть слово virtual или больше одной структуры с полями, то всё.

const86 ★★★★★
()

Например, данных, которые уйдут по сети или в файл

Если данные уходят в сеть или файл, то лучше использовать специализированные инструменты сериализации данных, а не колупаться с представлением структур в памяти (да еще рассчитывая, что оно не будет зависеть от компилятора и типа процессора).

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

во всех.


$ cat test.cpp 
#include <iostream>

struct A
{
    int i;
};

struct B: A
{
    int ii;
};


int main()
{
    std::cout << std::is_standard_layout<B>::value << ' ' << std::is_pod<B>::value << std::endl;
}
$ clang++ test.cpp -std=c++11
$ ./a.out 
0 0
Gvidon ★★★★
()
struct B {
    A a;
    int c, d;

    operator A&() { return a; }
    operator const A&() const { return a; }
};

POD может включать в себя другие POD, но не наследовать.

anonymous
()
Ответ на: комментарий от Gvidon

Автора, видимо, должно интересовать std::is_standard_layout и std::is_trivially_copyable.

asaw ★★★★★
()
Ответ на: комментарий от Gorthauer

В C++11 вроде эту гарантию дали.

В C++11 B - тривиальный тип, но это про инициализацию, а не про представление в памяти.

asaw ★★★★★
()

Как известно, в C++ структуры можно наследовать.

И забудь об этом. Для наследования есть классы. Для уменьшения разночтений, поведение структур рекомендуется оставлять на уровне Си, и использовать только для пассивных объектов,

Допустимо ли использовать наследование структур для описания вещей, у которых важно внутреннее представление (оно не должно зависеть от версии компилятора, типа процессора, ОС и т. д.)? Например, данных, которые уйдут по сети или в файл (разумеется, добавить к описанию всех структур __attribute__((packed)) в таком случае)?

Даже если ты будешь использовать типы вида int32_t, остаётся вопрос порядка байт. Для сети/файлов/т.п. есть 100500 форматов и библиотек. [Binary serialization formats]. Зачем кодить лишние велосипеды?

AlexVR ★★★★★
()

Например, данных, которые уйдут по сети или в файл

Не делай так. Это прямой путь на грабли. Используй сериализацию.

invy ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.