std::string x(x);
Esto se cuelga muy mal en mi compilador. ¿Significa esto que debería probar this != &that
en mis propios constructores de copia, o puedo suponer que ningún cliente será tan estúpido?std :: cadena x (x);
std::string x(x);
Esto se cuelga muy mal en mi compilador. ¿Significa esto que debería probar this != &that
en mis propios constructores de copia, o puedo suponer que ningún cliente será tan estúpido?std :: cadena x (x);
Inicializar algo consigo mismo es un comportamiento indefinido, lo que probablemente incluso podría significar que una vez que se invoca, ni siquiera se puede detectar más tarde. Supongamos que el compilador lo detecta y, por despecho, genera un ensamble para los demonios nasales, ¿no es una llamada a su constructor de copia?
En la práctica, puede suponer que el cliente no es tan estúpido, y si lo es, es asunto suyo depurarlo y resolverlo.
¿Dónde dice exactamente el estándar que esto es un comportamiento indefinido? – fredoverflow
Honestamente, estoy sorprendido de que compila. El problema es que el constructor de copias de 'std :: string' intentará llamar a métodos/datos de acceso en' x', pero 'x' aún no se ha construido. Por lo tanto, es un comportamiento indefinido porque estaría tratando de hacer cosas con una variable que aún no se ha construido. –
@FredOverflow: creo que una parte del estándar que es relevante es el "punto de declaración" (3.3.1). También es posible que esto tenga algunos usos significativos, por ejemplo, supongamos que la clase almacena una referencia a otra instancia de la clase (o a sí misma), entonces podríamos hacer, por ejemplo: 'X x (" self ", x); X y ("other", x); 'etc. En tal caso, supongo que las reglas serían similares en cuanto a usar ** this ** en una lista de inicialización de clases. – UncleBens
No debe probar el código que intenta fallar. Ver Null References. Dice
"Al igual que debe asumir que un puntero no nulo es válido, debe suponer que una referencia es válida. Debe tener fe en sus compañeros programadores".
Quiero complementar
... usted debe asumir que el origen de una copia es válida.
Si "arreglas" tu caso, ¿qué hacer para éste?
string x = string(x);
Ese código no es correcto de acuerdo a la norma y que no tiene sentido para comprobarlo y lo mejor que puede pasar es un fracaso rápido por lo que el usuario puede corregir su código.
¿Te refieres a los bloqueos del programa resultante o al compilador se bloquea? –
En un constructor de copia que no es necesario, pero debe verificarlo en un operador de asignación. –
El programa resultante se bloquea en el tiempo de ejecución. – fredoverflow