Por favor, escriba una lista de tareas que un constructor de copia y operador de asignación tienen que hacer en C++ para mantener la seguridad de excepción, evitar pérdidas de memoria, etc.Lista de verificación para la escritura de constructor de copia y operador de asignación en C++
Respuesta
Primero asegúrese de que realmente necesita apoyar la copia. La mayoría de las veces no es el caso, y por lo tanto deshabilitar ambos es el camino a seguir.
A veces, aún necesitará proporcionar duplicación en una clase de una jerarquía polimórfica, en ese caso: deshabilitar el operador de asignación, escribir un constructor de copia (¿protegido?) Y proporcionar una función virtual clone().
De lo contrario, en el caso de que esté escribiendo una clase de valor, está de regreso en la tierra de la forma canónica ortogonal de Coplien. Si tiene un miembro que no puede copiarse trivialmente, deberá proporcionar un constructor de copia, un destructor, un operador de asignación y un constructor predeterminado. Esta regla puede ser refinada, véase por ejemplo: The Law of The Big Two
También me gustaría recomendar a echar un vistazo a C++ FAQ regarding assignment operators, y al copy-and-swap idiom y al GOTW.
no tengo ni idea acerca excepción de forma segura aquí, pero voy por aquí. Imaginemos que es una envoltura de matriz modelada. Espero que ayude :)
Array(const Array& rhs)
{
mData = NULL;
mSize = rhs.size();
*this = rhs;
}
Array& operator=(const Array& rhs)
{
if(this == &rhs)
{
return *this;
}
int len = rhs.size();
delete[] mData;
mData = new T[len];
for(int i = 0; i < len; ++i)
{
mData[i] = rhs[i];
}
mSize = len;
return *this;
}
Este código no está a salvo excepción. ¡Siempre asigne antes de soltar! –
No, no lo es. No tuve problemas con el código de excepción de seguridad, así que nunca tuve la oportunidad de practicarlo. Este de arriba es solo snipper, normalmente usas contenedores STL. Por favor, publique su fragmento, me gustaría echarle un vistazo. – Nazgob
Hay muchos fragmentos en los enlaces que he proporcionado en mi respuesta. BTW, la prueba que impide la autoasignación se considera ahora como un anti-idioma (ahora que las excepciones se entienden mejor) –
Las versiones generadas por el compilador funcionan en la mayoría de las situaciones.
Necesita pensar un poco más sobre el problema cuando su objeto contiene un puntero RAW (un argumento para no tener punteros RAW). Entonces, si tiene un puntero RAW, la segunda pregunta es si posee el puntero (¿está siendo borrado por usted)? Si es así, deberá aplicar la regla de 4.
Poseer más de 1 puntero RAW se vuelve cada vez más difícil de hacer correctamente (El aumento en la complejidad tampoco es lineal [pero eso es observacional y no tengo estadísticas reales para volver a esa declaración]]. Entonces, si tiene más de 1 puntero RAW, piense en envolver cada uno en su propia clase (alguna forma de puntero inteligente).
Regla 4: Si un objeto es el dueño de un puntero RAW entonces es necesario definir los siguientes 4 miembros para asegurarse de que usted maneja la gestión de memoria correctamente:
- Constructor
- constructor de copia
- operador de asignación
- Destructor
cómo se defina éstas dependerán de la situat iones. Pero las cosas a tener en cuenta:
- defecto de construcción: Establecer puntero a NULL
- constructor de copia: utilizar la copia y de intercambio Ideum para proporcionar a la "Garantía de Excepción fuerte" operador
- Asignación: Check para la asignación a uno mismo
- Destructor: Protéjase de las excepciones que se propagan fuera del destructor.
"Las versiones generadas por el compilador funcionan en la mayoría de las situaciones". - dependiendo del tipo de programación que hagas. Incluso si todo se trata de indicadores inteligentes, que se ocupan del seguimiento de recursos y los problemas de excepción, una copia superficial puede no ser lo que quiere semánticamente. –
intente leer esto.
http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
es un muy buen análisis de Operador de asignación
Esto es típicamente lo que preguntaría en una entrevista. Sin embargo, veo una suposición falsa: que la mayoría de los objetos requieren ser copiables. "Cada objeto en un sistema C++ bien diseñado tiene un constructor predeterminado, un constructor de copia y un operador de asignación". Esta oración es para objetos basados en valores, no entidades. –
- 1. constructor de copia e implementación operador de asignación opciones -
- 2. Cuando debería definir mi propio operador de copia y asignación
- 3. operador de asignación sobrecarga en C++
- 4. El constructor de copias y el operador de asignación
- 5. ¿Bajo qué circunstancias debo proporcionar, operador de asignación, constructor de copia y destructor para mi clase de C++?
- 6. Python, copia en profundidad de la lista en la asignación
- 7. ¿Por qué sobrecargar el operador de asignación de copia para una clase singleton en C++?
- 8. C++ constructor de copia, los temporales y la semántica copia
- 9. ¿Es malo llamar al operador de asignación predeterminado desde el constructor de copia?
- 10. Operador de asignación de sobrecarga en C++
- 11. ¿Es posible escribir el operador de asignación de constructor solo mencionando miembros con copia especial?
- 12. Error con el constructor de copia/operador de asignación para una clase que tiene la variable de miembro std :: atomic
- 13. C++ sobrecarga operador de asignación
- 14. C++: implementar el constructor de copias y el operador de asignación de copias
- 15. Implementando el constructor de copia en términos de operador =
- 16. Reducción de la duplicación de código entre operator = y el constructor de copia
- 17. const en constructor de copia en C++
- 18. Por qué deshabilitar la asignación y el constructor de copia de CObject
- 19. C++ stl vector para las clases con copia privada constructor?
- 20. ¿Cómo usar los constructores y el operador de asignación de la clase base en C++?
- 21. copia y asignación
- 22. operador de asignación sobrecarga en C#
- 23. Creación de un constructor de copia de una lista enlazada
- 24. ¿Por qué haría que el constructor de copias y el operador de asignación fueran privados e implementados en C++?
- 25. constructor o constructor de copia?
- 26. previene la copia accidental de objetos en C++
- 27. ¿Por qué el operador de asignación llama al constructor?
- 28. implícito constructor de copia
- 29. C++: operador de asignación virtual puro
- 30. C#: Shift comportamiento operador de asignación izquierda
Pensé que se llamaba la regla de 4. –
AFAIK, se origina en el libro de Jim Coplien, de ahí el nombre - Por cierto, solo se aplica a las clases de valores. Algunos lo llaman la regla de cuatro. Hay (¿hubo?) También explicaciones sobre/Rule of Big Three/en C++ FAQ lite (no puedo encontrarlo más). Y se puede reducir a dos gracias a RAII. –
También protege contra la autoasignación en el operador de asignación. –