@larsmans ya ha respondido a su pregunta precisa, por lo que' ll en realidad digress: Este es un código de mierda!
La cuestión aquí es de 3 veces:
- Usted acaba de duplicar el código del constructor de copia (un poco)
strcpy
podría ser mejor sustituye por strncpy
, que hace algunos cota comprobar
- No es la excepción caja fuerte
1) y 2) son más agujas stic que nada, pero el 3) es una gran preocupación
EDIT: como señaló @Jerry Coffin, esto no protege contra la autoasignación. Es decir, si sobj
y _string
apuntan a la misma matriz de caracteres, tiene grandes problemas. La solución fácil al final de esta publicación también cubre esta situación.
No es seguro excepción
Vamos a echar un vistazo a una parte del código, es decir, la parte else
:
_size = strlen(sobj);
delete[] _string;
_string = new char[ _size + 1 ];
strcpy(_string, sobj);
¿Qué pasa si, por alguna razón, new
tiros?
_size
tiene el valor de la nueva cadena
_string
puntos al viejo puntero ... que ha sido liberado
Por lo tanto, no sólo el objeto se deja en un estado inutilizable (la mitad de sus datos del nuevo objeto, la mitad de la edad), pero no puede ni siquiera ser destruido (a menos que las fugas destructor ...?)
Adición de seguridad excepción, la forma más dura
_size = strlen(sobj);
delete[] _string;
try {
_string = new char[ _size + 1 ];
} catch(...) {
_size = 0; _string = 0;
throw;
}
strcpy(_string, sobj);
Está bien, es realmente la línea de fondo, pero nos trae la Garantía Excepción básico: hay garantía funcional, sino una garantía de que el código es técnicamente correcto (sin choque, sin fugas).
Adición de seguridad excepción, el camino más fácil: El lenguaje de copiar y de intercambio
Encuentra una descripción más completa en: What is the copy-and-swap idiom ?
void swap(String& lhs, String& rhs) {
using std::swap;
swap(lhs._size, rhs._size);
swap(lhs._string, rhs._string);
}
String& String::operator=(String other) { // pass-by-value
swap(*this, other);
return *this;
}
¿Cómo funciona?
- que volver a utilizar el constructor de copia para la copia real
- reutilizamos la función de intercambio de valores de intercambio
- reutilizamos el destructor para la limpieza
y es incluso mejor que el versión anterior también, por ahora tenemos Strong Exception Guarantee: es transaccional, por lo tanto si falla, la cadena que asignamos no cambia (como si nada hubiera sucedido).
More about Exception Guarantees.
estoy un poco desanimado de que un C++ tutorial promovería dicho código dudosa, rezar me dicen que es un ejemplo de lo que no debe hacer:/
Tenga en cuenta que la solución que se presenta en el libro no está a salvo excepción (y sería * realmente * simple hacerlo, realmente no entiendo por qué no lo hicieron). –