Copie profonde vs copie superficielle [dupliquer]

possibilité de dupliquer:

Quelle est la différence entre une copie profonde et une copie superficielle?

Quelle est la différence entre la profondeur et la copie superficielle. Quel type de copie fait un constructeur de copie?

47
demandé sur Community 2010-04-17 12:46:48

3 réponses

Copie peu profonde:

certains membres de la copie peuvent faire référence aux mêmes objets que l'original:

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

ici, le pi membre de l'original et copié X objet pointera tous les deux vers le même int .


copie en Profondeur:

tous les membres de l'original sont clonés (récursivement), si nécessaire). Il n'y a pas d'objets partagés:

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!
    { }
};

ici, le pi membre de l'original et copié X objet pointera vers différents int objets, mais les deux ont la même valeur.


le constructeur de copie par défaut (qui est automatiquement fourni si vous n'en fournissez pas un vous-même) ne crée que des copies superficielles.

Correction: plusieurs commentaires ci-dessous ont correctement souligné qu'il est faux de dire que la copie par défaut constructeur always effectue une copie superficielle (ou une copie profonde, d'ailleurs). Que le constructeur de copie d'un type crée une copie superficielle, ou une copie profonde, ou quelque chose entre les deux , dépend de la combinaison du comportement de copie de chaque membre; constructeur de copie peut être fait pour faire ce qu'il veut, après tout.

voici ce que la section 12.8, paragraphe 8 de la norme C++ de 1998 dit des exemples de code ci-dessus:

la copie implicitement définie constructeur pour la classe X exécute un memberwise copie de ses sous-objets. [...] Chaque sous-objet est copié dans le manière appropriée à son type: [...] [I]si le sous-objet est scalaire type, l'opérateur d'assignation de bâtiment est utiliser.

50
répondu stakx 2016-11-19 12:44:42

l'exemple par excellence de ceci est un tableau de pointeurs pour les structures ou les objets (qui sont mutables).

A copie superficielle copie le tableau et maintient des références aux objets originaux.

Un copie copie (clone) les objets de sorte qu'ils n'ont aucun rapport avec l'original. Implicitement, c'est que l'objet lui-même est profondément copié. C'est là que ça devient dur parce qu'il y a aucun moyen de savoir si quelque chose a été copié ou pas.

le constructeur de copie est utilisé pour initialiser le nouvel objet avec l'objet précédemment créé de la même classe. Par défaut compilateur a écrit une copie superficielle. La copie superficielle fonctionne bien quand l'allocation de mémoire dynamique n'est pas impliquée parce que quand l'allocation de mémoire dynamique est impliquée alors les deux objets pointent vers le même emplacement de mémoire dans un tas, donc pour supprimer ce problème nous avons écrit la copie profonde donc les deux les objets ont leur propre copie d'attributs dans une mémoire.

afin de lire les détails avec des exemples complets et des explications, vous pouvez voir l'article constructeurs et destructeurs .

le constructeur de copie par défaut est superficiel. Vous pouvez faire vos propres constructeurs de copie profonde ou peu profonde, comme approprié. Voir C++ Note: la programmation orientée objet: Copie des Constructeurs .

10
répondu cletus 2014-02-04 21:31:22

Deep copy effectue littéralement une copie profonde. Cela signifie que si votre classe a certains champs qui sont des références, leurs valeurs seront copiées, pas des références elles-mêmes. Si, par exemple, vous avez deux instances d'une classe, A & B avec des champs de type de référence, et effectuez une copie profonde, changer une valeur de ce champ dans A n'affectera pas une valeur dans B et inversement. Les choses sont différentes avec une copie superficielle, parce que seules les références sont copiées, donc, changer ce champ dans un objet copié affecterait l'objet original.

quel type de copie fait un constructeur de copie?

Il est dépendant de l'implémentation. Cela signifie qu'il n'y a pas de règles strictes à ce sujet, vous pouvez l'implémenter comme une copie profonde ou une copie superficielle, cependant autant que je sache c'est une pratique courante d'implémenter une copie profonde dans un constructeur de copie. Un défaut constructeur de copie effectue une copie superficielle.

2
répondu n535 2010-04-17 09:01:42