Directorio de artículos
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
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:
Resultado de analisis:
-
Primero, se construye el contenido del objeto str1
"Hello World!"
. -
Luego
浅拷贝
copie el contenido de str1 a str2 de la misma manera
str2 = str1
;. -
En este momento, se puede ver en el resultado de salida que el contenido de str1 y str2 es el mismo que "
Hello World!
" -
Cuando se cambia
str2[0]的字符为‘h’
, tanto str1 como str2 se emiten al mismo tiempohello 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:
resultado del análisis:
- 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
- Una vez que se opera str2, el contenido de str1 también cambiará;
- 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
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:
resultado del análisis:
-
Primero, se construye el contenido del objeto str1
"Hello World!"
. -
Luego
浅拷贝
copie el contenido de str1 a str2 de la misma manera
str2 = str1
;. -
En este momento, se puede ver en el resultado de salida que el contenido de str1 y str2 es el mismo que "
Hello World!
" -
Cuando se realiza el cambio
str2[0]的字符为‘h’
, str1 se emite al mismo tiempo o "Hello world!
", str2 se convierte enhello World!
. -
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
- 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.
- 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.