C ++ _ explicación detallada de copia profunda y superficial

1. Copia superficial

1.1 Concepto de copia superficial

  • También conocido como 值拷贝copiar el valor del objeto de origen en el objeto de copia de destino, en esencia, el objeto de origen y el objeto de copia de destino 共用一份实体, pero el nombre de la variable a la que se hace referencia es diferente, la dirección es en realidad la misma.
    Ejemplo: similar a la referencia en C ++, use diferentes nombres para apuntar al mismo bloque de dirección.

1.2 Icono de copia superficial

Inserte la descripción de la imagen aquí

1.3 Ejemplo de código de copia superficial

1.3.1 Sin destructor

#include<iostream>
#include<string>
#pragma warning(disable:4996)

using namespace std;

namespace mystring
{
    
    
	class string
	{
    
    
	public:
		string(const char* str = "")
			:_str(new char[strlen(str)+1])
		{
    
    
			strcpy(_str, str);
		}
		string& operator=(const string& s)
		{
    
    
			_str = s._str;
		}
		char& operator[](int i)
		{
    
    
			return _str[i];
		}

		const char* c_str()
		{
    
    
			return _str;
		}

	private:
		char* _str;
	};
}

int main()
{
    
    
	mystring::string str1("Hello World!\n");
	mystring::string str2 = str1;
	str2[0] = 'h';
	cout << str1.c_str()<< endl;
	cout << str2.c_str() << endl;
}

resultado de la operación:
Inserte la descripción de la imagen aquí

Resultado de analisis:

  1. Primero, se construye el contenido del objeto str1 "Hello World!".

  2. Luego 浅拷贝copie el contenido de str1 a str2 de la misma manera
    str2 = str1;.

  3. En este momento, se puede ver en el resultado de salida que el contenido de str1 y str2 es el mismo que " Hello World!"

  4. Cuando se cambia str2[0]的字符为‘h’, tanto str1 como str2 se emiten al mismo tiempo hello world!.

1.3.2 Destructor agregado

Parte del código, el resto del código es el mismo que el anterior sin destructor.


		const char* c_str()
		{
    
    
			return _str;
		}

		~string()
		{
    
    
			delete[] _str;
		}

	private:
		char* _str;
	};
}

Resultado de la operación:
Inserte la descripción de la imagen aquí
resultado del análisis:

  1. Después de agregar el destructor, ejecute un error.
    Razón: str1 llamó al destructor primero, y str1 destruyó la misma dirección cuando str2 llamó al destructor. Este también es el caso 浅拷贝常见的问题.

1.4 Resumen de copia superficial

  1. Una vez que se opera str2, el contenido de str1 también cambiará;
  2. Al desestructurar, primero se deconstruye str1 y luego str2.Sin embargo, dado que str1 y str2 apuntan al mismo espacio, la destrucción secundaria de un espacio dará lugar a errores.

解决出错问题便引入了深拷贝。

2 copia profunda

2.1 Concepto de copia profunda

  • 开辟和原空间大小相同的空间并将内容拷贝Vuelva a pasar la operación. Independientemente de si str1 se utiliza o no, se copiará una parte del espacio y el contenido del mismo tamaño.

2.2 Icono de copia profunda

Inserte la descripción de la imagen aquí

2.3 Ejemplo de código de copia profunda

#include<iostream>
#include<string>
#pragma warning(disable:4996)

using namespace std;

namespace mystring
{
    
    
	class string
	{
    
    
	public:
		string(const char* str = "")
			:_str(new char[strlen(str)+1])
		{
    
    
			strcpy(_str, str);
		}
		//现代写法
		string(const string& s)
			:_str(NULL)//为了交换以后tmp为NULL析构NULL。
		{
    
    
			string tmp(s._str);   
			swap(_str, tmp._str);  
		}
		//现代写法
		string& operator=(const string& s)
		{
    
    
			if (this != &s)
			{
    
    
				string tmp(s._str);    
				swap(_str, tmp._str);  
			}
			return *this;
		}
		
		char& operator[](int i)
		{
    
    
			return _str[i];
		}

		const char* c_str()
		{
    
    
			return _str;
		}

		~string()
		{
    
    
			delete[] _str;
		}

	private:
		char* _str;
	};
}

int main()
{
    
    
	mystring::string str1("Hello World!\n");
	mystring::string str2 = str1;
	cout << str1.c_str() << endl;
	cout << str2.c_str() << endl;
	str2[0] = 'h';
	cout << str1.c_str()<< endl;
	cout << str2.c_str() << endl;
}

Resultado de la operación:
Inserte la descripción de la imagen aquí
resultado del análisis:

  1. Primero, se construye el contenido del objeto str1 "Hello World!".

  2. Luego 浅拷贝copie el contenido de str1 a str2 de la misma manera
    str2 = str1;.

  3. En este momento, se puede ver en el resultado de salida que el contenido de str1 y str2 es el mismo que " Hello World!"

  4. Cuando se realiza el cambio str2[0]的字符为‘h’, str1 se emite al mismo tiempo o " Hello world!", str2 se convierte en hello World!.

  5. Cuando se destruye, str1 primero se deconstruye y luego str2 se deconstruye, pero como str1 y str2 apuntan a espacios diferentes, no reportará un error como una copia superficial.

2.4 Resumen de copia profunda

  1. Dado que el espacio se vuelve a abrir para str2 y el contenido de str1 se copia en el espacio recién abierto de str2, str2 tiene un nuevo espacio de direcciones, por lo que cambiar el contenido de str2 no afectará a str1.
  2. Incluso si se agrega la función de destructor, str1 se destruye primero y luego str2.Sin embargo, dado que str1 y str2 apuntan a espacios diferentes, no informará un error como una copia superficial.

Supongo que te gusta

Origin blog.csdn.net/weixin_45313447/article/details/115299372
Recomendado
Clasificación