Вопрос по c++ – Сравнение структур в C против C ++

1

Я хочу сравнить объекты класса / структуры C ++. В Си большую часть времени известен точный размерstruct суммируя размеры отдельных полей (при условии, что компилятор не добавляет отступы). Следовательно, можно использовать функцию memcmp () для двух объектов, чтобы сравнить их очень быстро. Я не уверен, работает ли то же самое для C ++. Это потому, что у класса также есть определения функций и, возможно, некоторые другие скрытые вещи (возможно, некоторая информация RTTI? Даже таблица виртуальных функций?)

Быстрая программа с простой структурой, содержащейint а такжеchar члены и функция показали, что размер структурыsizeof(int)+sizeof(char).

У меня есть один большой структурный класс с простыми типами данных int, char и т. Д. (Но их большое количество). Я хочу сравнивать объекты время от времени. Я не могу перегрузить== оператор как таковой заставит их сравнивать каждое поле по полю. В C я могу сравнить за один раз, используяmemcmp(), Какие-нибудь предложения для C ++? Могу ли я использоватьmemcmp() напрямую? Я не хочу, чтобы memcmp () потерпел неудачу, потому что некоторые другие значения, такие как таблица указателей виртуальных функций, отличаются (но все поля фактически равны) (Я использую g ++)

При неправильной упаковке (например, struct z {x char; y double;};), вы получите заполнение в структурах C. Было бы глупо предполагать, что вообще нет отступов, хотя вы, безусловно, можете минимизировать вероятность того, что это произойдет, если вы будете осторожны. Jonathan Leffler

Ваш Ответ

5   ответов
3

class или жеstruct не имеет ничего виртуального, "добавляя размеры отдельных полей (и предполагая, что компилятор не добавляет заполнение)" примерно так же правильно в C ++, как в C (то есть не совсем, потому что заполнениеis обычно добавляется ;-).

9

sizeof() структура или класс.

edit: since I provided the answer above, you have changed your question from "How can I manually determine the size of C++ structures and classes?" to a more general one about comparing two classes.

Короткий ответ: тыdo хочу перегрузить== оператор. Вера в то, что он будет сравнивать каждое поле по полю по одному, неверна; Вы можете перегрузитьoperator == использовать любой алгоритм, который вам нравится, в том числеmemcmp.

memcmp() На памяти от первого поля смещение до последнего должно работать нормально.memcmp() на всем участке класса может произойти сбой, если вы сравниваете класс типа A с другим классом B, который наследуется от A, поскольку указатели vtable могут отличаться.

Error: User Rate Limit Exceeded Methos
Error: User Rate Limit Exceeded Methos
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
10

The values in any padding is indeterminate and hence not comparable. If your machine is little-endian, comparing integer fields will produce one answer; if your machine is big-endian, it will produce another answer. Most people regard -1 as smaller than 0, but memcmp() will do byte-wise unsigned comparison, and will therefore treat -1 as bigger than 0. Any pointers are inherently not comparable relevantly by memcmp(). You cannot compare float or double using memcmp().

В общем, вы ищете бессмысленную оптимизацию.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededcanError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3

P.O.Ds безопасно сравнивать с memcmp.

Заполнение является проблемой для создания memcmp для объектов класса, так как он может быть заполнен мусором (который будет отличаться от объекта к объекту). В C вы обычно не сталкиваетесь с этой проблемой, потому что, как правило, нормально задавать всю структуру в 0 перед выполнением какого-либо присваивания, и это ОЧЕНЬ плохо в C ++, потому что вы можете перезаписать vtable.

Я не верю, что в спецификации языка есть что-то, что говорит о том, как реализованы виртуальные таблицы, хотя они обычно являются скрытыми членами данных. Таблица vtable должна быть одинаковой для членов одного и того же класса (но, конечно, будет отличаться для родительских / дочерних классов). Когда вы получаете множественное или виртуальное наследование, реализация может быть даже более разнообразной от компилятора к компилятору.

0

вы можете предотвратить заполнение в структурах с помощью #pragma pack (НКУ, VC ++)

#pragma pack(push, 1)
struct Example
{
   int a;
   char b;
   short c;
};
#pragma pack(pop)

Печать sizeof (Пример) показывает, что это 7 байтов. Без пакета #pragma размер составляет 8 байт.

Error: User Rate Limit Exceeded

Похожие вопросы