Qual é a diferença entre uma cópia profunda e uma cópia superficial?


754

Qual é a diferença entre uma cópia profunda e uma cópia superficial?


6
De que tecnologia ela se enquadra?
perfil completo de Suresh Varma

42
@SureshVarma, é um conceito de programação!
Manish Shrivastava

Respostas:


761

Cópias rasas duplicam o mínimo possível. Uma cópia superficial de uma coleção é uma cópia da estrutura da coleção, não dos elementos. Com uma cópia superficial, duas coleções agora compartilham os elementos individuais.

Cópias profundas duplicam tudo. Uma cópia profunda de uma coleção é composta por duas coleções com todos os elementos da coleção original duplicados.


Pode ser .NET MemberwiseClone () implementação fazer mais do que superficial copiar no sentido convencional
Lu55

5
Lembre-se de que também existem cópias mistas (não apenas cópias preguiçosas ), que duplicam apenas parte dela ( aqui está uma instância )! ;)
cregox

Portanto, uma cópia superficial de X pode alterar os elementos em X, mas uma cópia profunda não pode?
punstress

1
o que é uma estrutura de coleção?
Mel

1
As coleções @Honey podem ser diversas estruturas de dados que armazenam vários itens de dados. Em python temos tupla, lista, dictionery, etc
Murphy

852

Largura x Profundidade; pense em termos de uma árvore de referências com seu objeto como o nó raiz.

Raso:

Antes da cópia Cópia superficial Raso Feito

As variáveis ​​A e B se referem a diferentes áreas da memória, quando B é atribuído a A, as duas variáveis ​​se referem à mesma área da memória. Modificações posteriores no conteúdo de um são refletidas instantaneamente no conteúdo de outros, à medida que compartilham o conteúdo.

Profundo:

Antes da cópia Cópia em profundidade Deep Done

As variáveis ​​A e B se referem a diferentes áreas da memória, quando B é atribuído a A, os valores na área de memória que A aponta para são copiados na área de memória para a qual B aponta. Modificações posteriores no conteúdo de um permanecem exclusivas de A ou B; o conteúdo não é compartilhado.


33
Aqui está o artigo da Wikipedia que esta ilustração vem no caso, não faz sentido fora do contexto para você en.wikipedia.org/wiki/Object_copy#Shallow_copy
Corbin

4
Em caso de cópia superficial, se fizermos alterações na matriz B, isso será refletido na matriz A, pois A e B apontam para o mesmo local de memória?
Tek3

3
Em linha única, sua cópia por referência vs cópia por valor. Não tenho certeza se a resposta está correta!
Mannu

2
imagens diretamente tomado do wikipedia sem citação
jasonleonhard

10
@jasonleonhard Então, há 9 anos, acabei de colocar URLs nas imagens porque a incorporação de imagens não era suportada. Assim, o URL citou sua fonte. Mais tarde, a comunidade transformou os URLs em imagens incorporadas sem editar algum tipo de citação. O comentário principal de 4 anos também aponta o que você aponta. Dê uma olhada: stackoverflow.com/posts/184780/revisions Por que não editar apenas uma citação na resposta? Talvez eu esteja indisponível na próxima vez que alguém tiver alguma reclamação sobre meu estilo de escrita de 10 anos.
dlamblin 7/09/17

156

Em resumo, depende de quais pontos apontam para o quê. Em uma cópia superficial, o objeto B aponta para a localização do objeto A na memória. Na cópia em profundidade, todas as coisas na localização da memória do objeto A são copiadas para a localização da memória do objeto B.

Este artigo wiki tem um ótimo diagrama.

http://en.wikipedia.org/wiki/Object_copy


114

Tente considerar a seguinte imagem

insira a descrição da imagem aqui

Por exemplo, Object.MemberwiseClone cria um link de cópia superficial

e usando ICloneable interface que você pode obter profunda cópia como descrito aqui


28
Uma imagem vale mais que mil palavras.
Levi Fuller

6
Oh garoto, veio aqui para descobrir o significado. Esta é a única resposta que ajudou.
Karan Singh

1
Este é o mais simples e ainda mostra apenas o que é necessário.
hina10531

1
a melhor ilustração
Muhammad Nayab

69

Especialmente para desenvolvedores de iOS:

Se Bfor uma cópia superficial de A, para dados primitivos é como B = [A assign];e para objetos é como B = [A retain];

B e A apontam para o mesmo local de memória

Se Bé uma cópia profunda de A, é comoB = [A copy];

B e A apontam para diferentes locais de memória

O endereço de memória B é igual ao de A

B tem o mesmo conteúdo que A


8
"O endereço de memória B é igual ao de A" - Como é que é?

2
No Deep Copy, "o endereço de memória B NÃO é igual ao de A"
ismail baig

60

Cópia rasa: copia os valores dos membros de um objeto para outro.

Cópia profunda: copia os valores dos membros de um objeto para outro.
                     Quaisquer objetos ponteiros são duplicados e copiados em profundidade.

Exemplo:

class String
{
     int   size;
     char* data;
};

String  s1("Ace");   // s1.size = 3 s1.data=0x0000F000

String  s2 = shallowCopy(s1);
 // s2.size =3 s2.data = 0X0000F000
String  s3 = deepCopy(s1);
 // s3.size =3 s3.data = 0x0000F00F
 //                      (With Ace copied to this location.)

47

Eu não vi uma resposta curta e fácil de entender aqui - então vou tentar.

Com uma cópia superficial, qualquer objeto apontado pela fonte também é apontado pelo destino (para que nenhum objeto referenciado seja copiado).

Com uma cópia detalhada, qualquer objeto apontado pela fonte é copiado e a cópia é apontada pelo destino (portanto, agora haverá 2 de cada objeto referenciado). Isso ocorre novamente na árvore de objetos.



36

{Imagine dois objetos: A e B do mesmo tipo _t (com relação ao C ++) e você está pensando em copiar superficialmente / profundamente A para B}

Cópia superficial: Simplesmente faça uma cópia da referência de A em B. Pense nela como uma cópia do endereço de A. Portanto, os endereços de A e B serão os mesmos, ou seja, estarão apontando para o mesmo local da memória, ou seja, o conteúdo dos dados.

Cópia detalhada: Simplesmente faz uma cópia de todos os membros de A, aloca memória em um local diferente para B e depois atribui os membros copiados a B para obter uma cópia profunda. Dessa forma, se A se tornar inexistente, B ainda será válido na memória. O termo correto a ser usado seria clonagem, onde você sabe que os dois são totalmente iguais, mas ainda assim diferentes (ou seja, armazenados como duas entidades diferentes no espaço da memória). Você também pode fornecer seu wrapper de clone, onde pode decidir, por meio da lista de inclusão / exclusão, quais propriedades selecionar durante a cópia em profundidade. Essa é uma prática bastante comum quando você cria APIs.

Você pode optar por fazer uma cópia rasa ONLY_IF se entender as apostas envolvidas. Quando você tem um número enorme de ponteiros para lidar em C ++ ou C, fazer uma cópia superficial de um objeto é REALMENTE uma má idéia.

EXAMPLE_OF_DEEP COPY_ Um exemplo é que, quando você está tentando fazer o processamento de imagens e o reconhecimento de objetos, precisa mascarar "Movimento irrelevante e repetitivo" fora de suas áreas de processamento. Se você estiver usando ponteiros de imagem, poderá ter a especificação para salvar essas imagens de máscara. AGORA ... se você fizer uma cópia superficial da imagem, quando as referências do ponteiro forem KILLED da pilha, você perderá a referência e sua cópia, ou seja, haverá um erro de tempo de execução da violação de acesso em algum momento. Nesse caso, o que você precisa é de uma cópia profunda da sua imagem CLONANDO-a. Dessa forma, você pode recuperar as máscaras, caso precise delas no futuro.

EXAMPLE_OF_SHALLOW_COPY Não tenho muito conhecimento em comparação com os usuários do StackOverflow, portanto, sinta-se à vontade para excluir esta parte e dar um bom exemplo, se puder esclarecer. Mas eu realmente acho que não é uma boa idéia fazer uma cópia superficial se você souber que seu programa será executado por um período infinito de tempo, isto é, operação contínua de "push-pop" sobre a pilha com chamadas de função. Se você está demonstrando algo para uma pessoa amadora ou iniciante (por exemplo, material tutorial em C / C ++), provavelmente está tudo bem. Mas se você estiver executando um aplicativo, como um sistema de vigilância e detecção, ou o Sonar Tracking System, não deverá copiar superficialmente seus objetos, pois isso matará seu programa mais cedo ou mais tarde.


32
char * Source = "Hello, world.";

char * ShallowCopy = Source;    

char * DeepCopy = new char(strlen(Source)+1);
strcpy(DeepCopy,Source);        

'ShallowCopy' aponta para o mesmo local na memória que 'Source'. 'DeepCopy' aponta para um local diferente na memória, mas o conteúdo é o mesmo.


22

O que é cópia rasa?

Cópia rasa é uma cópia em bits de um objeto. Um novo objeto é criado com uma cópia exata dos valores no objeto original. Se qualquer um dos campos do objeto for referência a outros objetos, apenas os endereços de referência serão copiados, ou seja, somente o endereço de memória será copiado.Cópia rasa

Nesta figura, os MainObject1campos temfield1 do tipo int e ContainObject1do tipo ContainObject. Quando você faz uma cópia superficial de MainObject1, MainObject2é criada field2contendo o valor copiado field1e ainda apontando para ContainObject1si mesma. Observe que, como field1é do tipo primitivo, seu valor é copiado para, field2mas como ContainedObject1é um objeto, MainObject2ainda aponta para ContainObject1. Portanto, quaisquer alterações feitas no ContainObject1in MainObject1serão refletidas MainObject2.

Agora, se essa é uma cópia superficial, vamos ver o que é cópia profunda?

O que é cópia profunda?

Uma cópia profunda copia todos os campos e faz cópias da memória alocada dinamicamente, apontada pelos campos. Uma cópia profunda ocorre quando um objeto é copiado junto com os objetos aos quais se refere. Cópia profunda

Nesta figura, o MainObject1 possui campos field1 do tipo int e ContainObject1do tipo ContainObject. Quando você faz uma cópia profunda de MainObject1, MainObject2é criado field2contendo o valor copiado de field1e ContainObject2contendo o valor copiado de ContainObject1. Observe que quaisquer alterações feitas em ContainObject1in MainObject1não serão refletidas em MainObject2.

bom artigo


não é sua culpa, embora este exemplo se refira a um caso em field3que, em posição de tentar compreender algo tão profundo quanto esse problema, onde está ocorrendo o número 3 desse exemplo ContainObject2 ?
Robb_2015

16

Na programação orientada a objetos, um tipo inclui uma coleção de campos membros. Esses campos podem ser armazenados por valor ou por referência (ou seja, um ponteiro para um valor).

Em uma cópia superficial, uma nova instância do tipo é criada e os valores são copiados para a nova instância. Os ponteiros de referência também são copiados como os valores. Portanto, as referências estão apontando para os objetos originais. Quaisquer alterações nos membros que são armazenadas por referência aparecem no original e na cópia, já que nenhuma cópia foi feita do objeto referenciado.

Em uma cópia detalhada, os campos armazenados por valor são copiados como antes, mas os ponteiros para objetos armazenados por referência não são copiados. Em vez disso, é feita uma cópia profunda do objeto referenciado e um ponteiro para o novo objeto é armazenado. Quaisquer alterações feitas nos objetos referenciados não afetarão outras cópias do objeto.


12

'ShallowCopy' aponta para o mesmo local na memória que 'Source'. 'DeepCopy' aponta para um local diferente na memória, mas o conteúdo é o mesmo.


Isso é um pouco enganador. Uma cópia superficial e profunda copiará o objeto para um novo local na memória, uma cópia profunda também copiará os objetos filhos, enquanto uma cópia superficial apenas fará com que os novos objetos se refiram aos filhos antigos. É difícil de ler sem se referir ao objeto original.
Bill K

10

Clonagem
rasa : Definição: "Uma cópia superficial de um objeto copia o objeto 'principal', mas não copia os objetos internos." Quando um objeto personalizado (por exemplo, Employee) possui variáveis ​​primitivas do tipo String, você usa a Clonagem rasa.

Employee e = new Employee(2, "john cena");
Employee e2=e.clone();

Você retorna super.clone();no método clone () substituído e seu trabalho termina.

Clonagem Profunda :
Definição: "Ao contrário da cópia superficial, uma cópia profunda é uma cópia totalmente independente de um objeto".
Significa quando um objeto Employee mantém outro objeto customizado:

Employee e = new Employee(2, "john cena", new Address(12, "West Newbury", "Massachusetts");

Então você deve escrever o código para clonar o objeto 'Address' também no método clone () substituído. Caso contrário, o objeto Address não será clonado e causará um erro quando você alterar o valor de Address no objeto Employee clonado, o que reflete o original também.


8
var source = { firstName="Jane", lastname="Jones" };
var shallow = ShallowCopyOf(source);
var deep = DeepCopyOf(source);
source.lastName = "Smith";
WriteLine(source.lastName); // prints Smith
WriteLine(shallow.lastName); // prints Smith
WriteLine(deep.lastName); // prints Jones

Esse não é um bom exemplo. As cópias rasas são usadas principalmente para cópia rápida de objetos, sem copiar os dados, mas quando um objeto precisa modificar os dados compartilhados, é feita uma cópia profunda dos mesmos. Seu exemplo provavelmente confundirá os iniciantes.
CMircea

isso funciona apenas em idiomas que usam ponteiros para representar seqüências de caracteres. O ponto que o DHA está tentando destacar é que a cópia superficial apenas duplica os ponteiros para o conteúdo original (singular) idêntico, enquanto a cópia profunda clona o conteúdo referenciado dos ponteiros também. Ambos os métodos copiam o conteúdo da superfície. Se o idioma armazenar seqüências de caracteres como conteúdo literal de superfície, por exemplo, dentro de um cabeçalho WAV, este exemplo não funcionará. Observe que isso provavelmente é muito exigente para a maioria dos problemas da vida real que não são esotéricos.
DragonLord 16/11

8

Cópia profunda

Uma cópia profunda copia todos os campos e faz cópias da memória alocada dinamicamente, apontada pelos campos. Uma cópia profunda ocorre quando um objeto é copiado junto com os objetos aos quais se refere.

Cópia rasa

Cópia rasa é uma cópia em bits de um objeto. Um novo objeto é criado com uma cópia exata dos valores no objeto original. Se algum dos campos do objeto for referência a outros objetos, apenas os endereços de referência serão copiados, ou seja, somente o endereço de memória será copiado.


Infelizmente, esse link não funciona mais - agora aponta para um artigo de fevereiro de 2019 sobre web design (a menos que o autor seja clarividente?).
PhilPhil

7

Cópia rasa - A variável de referência dentro dos objetos originais e copiados em pouca profundidade tem referência ao objeto comum .

Cópia Profunda - A variável de referência dentro de objetos originais e copiados em profundidade tem referência a objetos diferentes .

O clone sempre faz uma cópia superficial.

public class Language implements Cloneable{

    String name;
    public Language(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

classe principal está seguindo-

public static void main(String args[]) throws ClassNotFoundException, CloneNotSupportedException{

      ArrayList<Language> list=new ArrayList<Language>();
      list.add(new Language("C"));
      list.add(new Language("JAVA"));

      ArrayList<Language> shallow=(ArrayList<Language>) list.clone();
      //We used here clone since this always shallow copied.

      System.out.println(list==shallow);

      for(int i=0;i<list.size();i++)
      System.out.println(list.get(i)==shallow.get(i));//true

      ArrayList<Language> deep=new ArrayList<Language>();
      for(Language language:list){
          deep.add((Language) language.clone());
      }
      System.out.println(list==deep);
      for(int i=0;i<list.size();i++)
          System.out.println(list.get(i)==deep.get(i));//false

} 

O resultado acima será

falso verdadeiro verdadeiro

falso falso falso

Qualquer alteração feita no objeto original irá refletir no objeto raso e não no objeto profundo.

  list.get(0).name="ViSuaLBaSiC";
  System.out.println(shallow.get(0).getName()+"  "+deep.get(0).getName());

OutPut- ViSuaLBaSiC C


7

Eu gostaria de dar um exemplo, e não a definição formal.

var originalObject = { 
    a : 1, 
    b : 2, 
    c : 3,
};

Este código mostra uma cópia superficial :

var copyObject1 = originalObject;

console.log(copyObject1.a);         // it will print 1 
console.log(originalObject.a);       // it will also print 1 
copyObject1.a = 4; 
console.log(copyObject1.a);           //now it will print 4 
console.log(originalObject.a);       // now it will also print 4

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // now it will print 1

Este código mostra uma cópia detalhada :

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // !! now it will print 1 !!

Estou recebendo #1 1 4 4 4 4 4 4
Suresh Prajapati

na cópia em profundidade, copieObjeto.a = 8 e verifique. espero que você obtenha uma resposta adequada.
Vivek Mehta

5
struct sample
{
    char * ptr;
}
void shallowcpy(sample & dest, sample & src)
{
    dest.ptr=src.ptr;
}
void deepcpy(sample & dest, sample & src)
{
    dest.ptr=malloc(strlen(src.ptr)+1);
    memcpy(dest.ptr,src.ptr);
}

5

Em termos simples, uma cópia rasa é semelhante a chamada por referência e uma cópia profunda é semelhante a chamada por valor

Em Chamada por referência, os parâmetros formais e reais de uma função se referem ao mesmo local de memória e ao valor.

Em Chamada por valor, os parâmetros formais e reais de uma função se referem a um local de memória diferente, mas com o mesmo valor.


5

Imagine que existem duas matrizes chamadas arr1 e arr2.

arr1 = arr2;   //shallow copy
arr1 = arr2.clone(); //deep copy

5

Uma cópia superficial constrói um novo objeto composto e insere suas referências ao objeto original.

Diferentemente da cópia superficial, a cópia em profundidade constrói o novo objeto composto e também insere cópias dos objetos originais do objeto composto original.

Vamos dar um exemplo.

import copy
x =[1,[2]]
y=copy.copy(x)
z= copy.deepcopy(x)
print(y is z)

O código acima imprime FALSE.

Vamos ver como.

Objeto composto original x=[1,[2]](chamado como composto porque possui objeto dentro do objeto (Inception))

insira a descrição da imagem aqui

como você pode ver na imagem, há uma lista dentro da lista.

Em seguida, criamos uma cópia superficial usando y = copy.copy(x). O que o python faz aqui é: ele criará um novo objeto composto, mas os objetos dentro deles estão apontando para os objetos originais.

insira a descrição da imagem aqui

Na imagem, ele criou uma nova cópia para a lista externa. mas a lista interna permanece a mesma da lista original.

Agora criamos uma cópia em profundidade dele usando z = copy.deepcopy(x). o que o python faz aqui é, ele criará um novo objeto para a lista externa e a lista interna. como mostrado na imagem abaixo (destacado em vermelho).

insira a descrição da imagem aqui

No final, o código é impresso False, pois y e z não são os mesmos objetos.

HTH.


2

A cópia rasa é criar um novo objeto e, em seguida, copiar os campos não estáticos do objeto atual para o novo objeto. Se um campo for um tipo de valor -> é executada uma cópia bit a bit do campo; para um tipo de referência -> a referência é copiada, mas o objeto referido não é; portanto, o objeto original e seu clone se referem ao mesmo objeto.

A cópia profunda está criando um novo objeto e, em seguida, copiando os campos não estáticos do objeto atual para o novo objeto. Se um campo é um tipo de valor -> é executada uma cópia bit a bit do campo. Se um campo for um tipo de referência -> uma nova cópia do objeto referido será executada. As classes a serem clonadas devem ser sinalizadas como [Serializable].


2

Retirado de [blog]: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

A cópia profunda envolve o uso do conteúdo de um objeto para criar outra instância da mesma classe. Em uma cópia detalhada, os dois objetos podem conter as mesmas informações, mas o objeto de destino terá seus próprios buffers e recursos. a destruição de qualquer objeto não afetará o objeto restante. O operador de atribuição sobrecarregado criaria uma cópia profunda dos objetos.

Cópia rasa envolve copiar o conteúdo de um objeto em outra instância da mesma classe, criando assim uma imagem espelhada. Devido à cópia direta de referências e ponteiros, os dois objetos compartilharão o mesmo conteúdo externo do outro objeto, de forma imprevisível.

Explicação:

Usando um construtor de cópia, simplesmente copiamos os valores dos dados membro por membro. Esse método de cópia é chamado de cópia superficial. Se o objeto for uma classe simples, composta de tipos incorporados e sem ponteiros, isso seria aceitável. Essa função usaria os valores e os objetos e seu comportamento não seria alterado com uma cópia superficial, apenas os endereços dos ponteiros que são membros são copiados e não o valor para o qual o endereço está apontando. Os valores dos dados do objeto seriam alterados inadvertidamente pela função. Quando a função sai do escopo, a cópia do objeto com todos os seus dados é removida da pilha.

Se o objeto tiver ponteiros, é necessário executar uma cópia profunda. Com a cópia profunda de um objeto, a memória é alocada para o objeto no armazenamento gratuito e os elementos apontados são copiados. Uma cópia detalhada é usada para objetos retornados de uma função.


2

Para adicionar mais a outras respostas,

  • uma cópia rasa de um objeto executa cópia por valor para propriedades baseadas em tipos de valor e cópia por referência para propriedades baseadas em tipos de referência.
  • uma Cópia Profunda de um objeto executa cópia por valor para propriedades baseadas em tipos de valor, bem como cópia por valor para propriedades baseadas em tipos de referência na hierarquia (dos tipos de referência)

2

A cópia rasa não criará nova referência, mas a cópia profunda criará a nova referência.

Aqui está o programa para explicar a cópia profunda e superficial.

public class DeepAndShollowCopy {
    int id;
    String name;
    List<String> testlist = new ArrayList<>();

    /*
    // To performing Shallow Copy 
    // Note: Here we are not creating any references. 
      public DeepAndShollowCopy(int id, String name, List<String>testlist)
       { 

       System.out.println("Shallow Copy for Object initialization");
       this.id = id; 
       this.name = name; 
       this.testlist = testlist; 

       }
    */  

    // To performing Deep Copy 
    // Note: Here we are creating one references( Al arraylist object ). 
    public DeepAndShollowCopy(int id, String name, List<String> testlist) {
        System.out.println("Deep Copy for Object initialization");
        this.id = id;
        this.name = name;
        String item;
        List<String> Al = new ArrayList<>();
        Iterator<String> itr = testlist.iterator();
        while (itr.hasNext()) {
            item = itr.next();
            Al.add(item);
        }
        this.testlist = Al;
    }


    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Oracle");
        list.add("C++");
        DeepAndShollowCopy copy=new DeepAndShollowCopy(10,"Testing", list);
        System.out.println(copy.toString());
    }
    @Override
    public String toString() {
        return "DeepAndShollowCopy [id=" + id + ", name=" + name + ", testlist=" + testlist + "]";
    }
}

1

Copiando ararys:

Matriz é uma classe, o que significa que é o tipo de referência; portanto, matriz1 = matriz2 resulta em duas variáveis ​​que referenciam a mesma matriz.

Mas veja este exemplo:

  static void Main()
    {
        int[] arr1 = new int[] { 1, 2, 3, 4, 5 }; 
        int[] arr2 = new int[] { 6, 7, 8, 9, 0 };

        Console.WriteLine(arr1[2] + " " + arr2[2]);
        arr2 = arr1;
        Console.WriteLine(arr1[2] + " " + arr2[2]); 
        arr2 = (int[])arr1.Clone();
        arr1[2] = 12;
        Console.WriteLine(arr1[2] + " " + arr2[2]);
    }

clone superficial significa que apenas a memória representada pela matriz clonada é copiada.

Se a matriz contiver objetos do tipo valor, os valores serão copiados ;

se a matriz contiver um tipo de referência, apenas as referências serão copiadas. Portanto, existem duas matrizes cujos membros fazem referência aos mesmos objetos .

Para criar uma cópia detalhada - onde o tipo de referência é duplicado, você deve percorrer a matriz e clonar cada elemento manualmente.


Eu não sei sobre outras línguas, mas em C # / VB, a cópia superficial de uma matriz de tipos de valor não copia os valores. As duas matrizes se referem aos mesmos objetos. Adicionar um botão a um formulário e adicionar este código para ver:private void button1_Click(object sender, EventArgs e) { int[] arr1 = new int[]{1,2,3,4,5}; int[] arr2 = new int[]{6,7,8,9,0}; MessageBox.Show(arr1[2] + " " + arr2[2]); arr2 = arr1; MessageBox.Show(arr1[2] + " " + arr2[2]); arr1[2] = 12; MessageBox.Show(arr1[2] + " " + arr2[2]); }
DeanOC

você está certo, corrigi minha resposta para ser mais preciso, usando clone em matrizes. Você está absolutamente certo de que "copiar superficialmente uma matriz de tipos de valores não copia os valores", mas usar clone na matriz sim. Eu tentei explicar isso, tente. Graças
lukaszk

1

Eu vim a entender das seguintes linhas.

A cópia rasa copia um tipo de valor do objeto (int, float, bool) nos campos para o objeto de destino e os tipos de referência do objeto (string, classe etc.) são copiados como referências no objeto de destino. Nesse destino, os tipos de referência apontam para o local da memória do objeto de origem.

A cópia profunda copia o valor e os tipos de referência de um objeto em uma nova cópia completa dos objetos de destino. Isso significa que os tipos de valor e de referência receberão novos locais de memória.


0

Adicionando a todas as definições acima, uma cópia profunda mais comumente usada, está no construtor de cópias (ou oprator de atribuição de sobrecarga) da classe.

Cópia rasa -> é quando você não fornece um construtor de cópias. Aqui, apenas o objeto é copiado, mas nem todos os membros da classe são copiados.

Cópia profunda -> é quando você decide implementar o construtor de cópias ou a atribuição de sobrecarga em sua classe e permite copiar todos os membros da classe.

MyClass& MyClass(const MyClass& obj) // copy constructor for MyClass
{
          // write your code, to copy all the members and return the new object
}
MyClass& operator=(const MyClass& obj) // overloading assignment operator,
{
          // write your code, to copy all the members and return the new object
}

0

O construtor de cópia é usado para inicializar o novo objeto com o objeto criado anteriormente da mesma classe. Por padrão, o compilador escreveu uma cópia superficial. A cópia rasa funciona bem quando a alocação dinâmica de memória não está envolvida porque, quando a alocação dinâmica de memória está envolvida, os dois objetos apontam para o mesmo local da memória em um heap. Portanto, para remover esse problema, escrevemos uma cópia profunda para que os dois objetos tenham sua própria cópia dos atributos em uma memória. Para ler os detalhes com exemplos e explicações completos, você pode ver o artigo Construtores C ++ .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.