C ++ Deep Copy структуры, которая включает много простых переменных плюс одну вложенную структуру .. (memcpy?) - PullRequest
1 голос
/ 16 апреля 2011

У меня есть

struct  Parent
{
    int child1;
    int child2;
     char child3;
     float child 4;
     anotherStruct child5;
};

typedef struct
{
    unsigned char  x;
    int            y;
    char           z;
    float          a;
    int            b;
    char           c;
    etc ..
  } anotherStruct;

Parent   myFirstParent;
Parent   mySecondParent;

///I want to do a deep copy of myFirstParent into mySecondParent. 
//does the follwowing work for that purpose??
memcpy (&mySecondParent, &myFirstParent, sizeof(myFirstParent);

Я сам изучаю ответ, но в то же время я задаю вопрос из-за чрезвычайной нехватки времени.Заранее спасибо.

Ответы [ 4 ]

5 голосов
/ 16 апреля 2011

В вашем случае назначение должно работать просто отлично:

mySecondParent = myFirstParent;

В конце концов, ни одна из структур не определяет указатели.

Кроме того, если бы были указатели, даже memcpy не работал бы, так как он не делает глубокого копирования. В этом случае вам пришлось вручную скопировать содержимое указателей.

Кстати, ваш код не будет компилироваться, так как вы используете anotherStruct до его определения. Пожалуйста, определите anotherStruct до Parent.

1 голос
/ 16 апреля 2011

Поскольку в вашем классе нет указателей, то компилятор по умолчанию, сгенерированный версией конструктора копирования и оператора assignemnt, будет работать нормально (делая то, что вы называете глубокой копией).

Технически это мелкая копия. Глубокая копия - это когда ваш класс содержит указатели, и вам нужно сделать копии содержимого указателей.

Это должно работать нормально без memcpy (который никогда не должен использоваться для копирования объектов C ++)

Parent   p1;
Parent   p2(p1);   // Make a copy of p1 into p2.
Parent   p3;

p1 = p3; // Use assignment operator works fine.
1 голос
/ 16 апреля 2011

Как правило

Имейте в виду одну вещь: memcpy () это зло! Это конструкция C, которую вы никогда не должны использовать в C ++. memcpy () работает с битами и байтами, а не с объектами. В худшем случае он не учитывает то, что на самом деле хранится в копируемых объектах, что приводит к ошибочным результатам или даже к более уродливому коду, который учитывает особые случаи. Никогда не используйте memcpy () в коде C ++. Всегда есть лучшие, более объектно-ориентированные способы сделать то же самое.

Это может не относиться к вашему случаю, поскольку вы не используете бесплатный магазин, но иногда вы можете использовать бесплатный магазин.

ИСТОЧНИК

0 голосов
/ 16 апреля 2011

Простая структура заданий будет хорошо работать для вас.В общем, cimpiler (например, компилятор Microsoft и likey GCC) выберет наиболее эффективный способ копирования памяти.Для небольших или простых вещей серия загрузок и сохранений регистров часто наиболее эффективна.Компилятор может выбрать memcpy () для некоторых вещей.

Другие ответы указывают, что memcpy () никогда не должен использоваться с классами C ++.Это в целом правильно, но в некоторых случаях его можно использовать, если вы знаете, что делаете.Но это почти никогда не нужно.

На процессорах AMD и Intel x86 / x64 memcpy () всегда генерируется (или использует) инструкцию 'rep movd'.В течение многих, многих лет все современные процессоры оптимизированы для этой инструкции, имея специальный микрокод или другие внутренние функции, чтобы обеспечить эффективную работу с памятью малого и среднего размера.

Лучше всего просто посмотреть на сгенерированный код на ассемблере в вашем отладчике.Если ваше структурное назначение не заканчивается серией простых загрузок / хранилищ или memcopy (rep movd), то вы можете написать ее самостоятельно, используя memcpy ().Это будет хорошо работать, так как ваши классы и структуры используют "plain-old-data".Как сказано в ответе другого автора, если ваша структура содержит указатели, вам понадобится код для обработки таких объектов, как мелкие или глубокие копии или объекты с подсчетом ссылок.

Как всегда, для «горячих» путей кода, профилировщик и измерение производительностиявляются важными инструментами.

...