Diepe kopie vs Ondiepe kopie

mogelijk Duplicaat:
Wat is het verschil tussen een diepe kopie en een ondiepe kopie?

Wat is het verschil tussen diep en ondiepe kopie. Welk type een kopie doet een kopie-constructeur?


Antwoord 1, Autoriteit 100%

Ondiepe kopie:

Sommige leden van de kopie kunnen dezelfde objecten noemen als het origineel:

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

Hier, de piLid van het origineel en gekopieerd XOBJE ZAL ZELF NAAR DEZELFDE int.


Diepe kopie:

Alle leden van het origineel worden gekloneerd (recursief, indien nodig). Er zijn geen gedeelde objecten:

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

Hier, de piLid van het origineel en gekopieerd XObject zal wijzen op verschillende intobjecten, maar beide hebben hetzelfde waarde.


De standaardkopieerconstructeur (die automatisch wordt verstrekt als u zelf niet zelf geeft) maakt alleen ondiepe exemplaren.

Correctie:Verschillende opmerkingen hieronder hebben er terecht op gewezen dat het verkeerd is om te zeggen dat de standaard kopieerconstructor altijdeen ondiepe kopie uitvoert (of daarvoor een diepe kopie maakt) materie). Of de kopieerconstructor van een type een ondiepe kopie of een diepe kopie maakt, of iets daartussenin, hangt af van de combinatie van het kopieergedrag van elk lid; De kopieerconstructor van het type van een lid kan tenslotte worden gemaakt om te doen wat hij wil.

Dit is wat paragraaf 12.8, paragraaf 8 van de C++-standaard uit 1998 zegt over de bovenstaande codevoorbeelden:

De impliciet gedefinieerde kopie
constructor voor klasse Xvoert a . uit
lidgewijze kopie van zijn subobjecten.
[…] Elk subobject wordt gekopieerd in de
manier die past bij het type: […]
[I]f het subobject van het scalaire type is,
de ingebouwde toewijzingsoperator is
gebruikt.


Antwoord 2, autoriteit 25%

Het typische voorbeeld hiervan is een reeks verwijzingen naar structs of objecten (die veranderbaar zijn).

Een ondiepe kopiekopieert de array en behoudt de verwijzingen naar de originele objecten.

Een diepe kopiezal de objecten ook kopiëren (klonen), zodat ze geen relatie hebben met het origineel. Impliciet hierbij is dat het object zelf diep gekopieerd wordt. Dit is waar het moeilijk wordt omdat er geen echte manier is om te weten of iets diep is gekopieerd of niet.

De kopieerconstructor wordt gebruikt om het nieuwe object te initialiseren met het eerder gemaakte object van dezelfde klasse. Standaard schreef de compiler een ondiepe kopie. Ondiepe kopie werkt prima wanneer dynamische geheugentoewijzing niet betrokken is, omdat wanneer dynamische geheugentoewijzing betrokken is, beide objecten in een hoop naar dezelfde geheugenlocatie zullen wijzen. Daarom hebben we om dit probleem te verhelpen een diepe kopie geschreven, zodat beide objecten hun eigen kopie van attributen hebben in een herinnering.

Om de details met volledige voorbeelden en uitleg te lezen, kunt u het artikel Constructors and vernietigers.

De standaard kopieerconstructor is oppervlakkig. U kunt uw eigen kopieerconstructors diep of ondiep maken, al naar gelang van toepassing. Zie C++ Notes: OOP: Copy Constructors.


Antwoord 3, autoriteit 5%

Diepe kopie voert letterlijk een diepe kopie uit. Het betekent dat als uw klas enkele velden heeft die referenties zijn, hun waarden worden gekopieerd, niet de referenties zelf. Als u bijvoorbeeld twee instanties van een klasse heeft, kan A & B met velden van het referentietype, en voer een diepe kopie uit, het wijzigen van een waarde van dat veld in A heeft geen invloed op een waarde in B. En omgekeerd. Bij een oppervlakkige kopie ligt dit anders, omdat alleen referenties worden gekopieerd. Het wijzigen van dit veld in een gekopieerd object zou daarom van invloed zijn op het oorspronkelijke object.

Welk type kopie doet een kopie-constructor?

Het is implementatieafhankelijk. Dit betekent dat daar geen strikte regels voor zijn, je kunt het implementeren als een diepe kopie of een oppervlakkige kopie, maar voor zover ik weet is het gebruikelijk om een diepe kopie in een kopie-constructor te implementeren. Een standaard kopie-constructor voert echter een ondiepe kopie uit.

Other episodes