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

Глубокая копия против мелкой копии

Возможный дубликат:
В чем разница между глубокой копией и мелкой копией?

В чем разница между глубокой и мелкой копией. Какой тип копии выполняет конструктор копирования?

4b9b3361

Ответ 1

Неглубокая копия:

Некоторые члены копии могут ссылаться на те же объекты, что и оригинал:

class X
{
private:
    int i;
    int *pi;
public:
    X()
        : pi(new int)
    { }
    X(const X& copy)   // <-- copy ctor
        : i(copy.i), pi(copy.pi)
    { }
};

Здесь член pi исходного и скопированного объекта X будет указывать на тот же int.


Глубокая копия:

Все члены оригинала клонируются (рекурсивно, если необходимо). Нет общих объектов:

class X
{
private:
    int i;
    int *pi;
public:
    X()
        : pi(new int)
    { }
    X(const X& copy)   // <-- copy ctor
        : i(copy.i), pi(new int(*copy.pi))  // <-- note this line in particular!
    { }
};

Здесь член pi исходного и скопированного объекта X будет указывать на разные объекты int, но оба они имеют одинаковое значение.


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

Коррекция: Несколько комментариев ниже правильно указали, что неправильно утверждать, что конструктор копии по умолчанию всегда выполняет мелкую копию (или глубокую копию, если на то пошло). Независимо от того, создает ли конструктор типовой копии мелкую копию или глубокую копию или что-то среднее между двумя, зависит от комбинации поведения каждого члена-копии; конструктор копии типа члена может быть сделан, чтобы делать все, что захочет, в конце концов.

Вот какой раздел 12.8, пункт 8 стандарта С++ 1998 года, говорит о приведенных выше примерах кода:

Неявно определенная копия конструктор для класса X выполняет поместить копию его подобъектов. [...] Каждый подобъект копируется в способ, соответствующий его типу: [...] [I] f подобъект имеет скалярный тип, встроенный оператор присваивания б.

Ответ 2

Ключевым примером этого является массив указателей на структуры или объекты (которые изменяются).

A мелкая копия копирует массив и поддерживает ссылки на исходные объекты.

A глубокая копия скопирует (клонирует) объекты, чтобы они не имели никакого отношения к оригиналу. Неявным в этом является то, что сам объект сильно скопирован. Это то, где он становится тяжелым, потому что нет реального способа узнать, что что-то было глубоко скопировано или нет.

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

Чтобы прочитать подробности с полными примерами и пояснениями, вы можете увидеть статью Конструкторы и деструкторы.

Конструктор копии по умолчанию неглубокий. Вы можете сделать свои собственные конструкторы копий глубокими или неглубокими, в зависимости от ситуации. См. Заметки С++: ООП: Копировать конструкторы.

Ответ 3

Глубокая копия буквально выполняет глубокую копию. Это означает, что если ваш класс имеет некоторые поля, которые являются ссылками, их значения будут скопированы, а не сами ссылки. Если, например, у вас есть два экземпляра класса A и B с полями ссылочного типа и выполняют глубокую копию, изменение значения этого поля в не повлияет на значение в B. И наоборот. Вещи отличаются от мелкой копии, поскольку копируются только ссылки, поэтому изменение этого поля в скопированном объекте повлияет на исходный объект.

Какой тип копии выполняет конструктор копирования?

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