Lista de verificación para escribir el constructor de copia y el operador de asignación en C ++

StackOverflow https://stackoverflow.com/questions/214891

Pregunta

Escriba una lista de tareas que el constructor de copias y el operador de asignación deben realizar en C ++ para mantener la seguridad excepcional, evitar pérdidas de memoria, etc.

¿Fue útil?

Solución

Primero asegúrate de que realmente necesitas compatibilidad con 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 deberá proporcionar la 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 de clonar ().

De lo contrario, en el caso de que escriba una clase de valor, volverá a la tierra de la Forma canónica ortogonal de Coplien. Si tiene un miembro que no se puede copiar de forma trivial, deberá proporcionar un constructor de copia, un destructor, un operador de asignación y un constructor predeterminado. Esta regla puede ser refinada, ver por ejemplo: La Ley de los Dos Grandes

También recomendaría consultar Preguntas frecuentes sobre C ++ relacionadas con los operadores de asignación , y en idioma de copia e intercambio y en GOTW .

Otros consejos

Las versiones generadas por el compilador funcionan en la mayoría de las situaciones.

Debe pensar un poco más en el problema cuando su objeto contiene un puntero RAW (un argumento para no tener punteros RAW). Así que tienes un puntero RAW, la segunda pregunta es ¿tienes el puntero (estás siendo eliminado por ti)? Si es así, deberá aplicar la regla de 4.

Ser propietario de más de 1 puntero RAW se vuelve cada vez más difícil de hacer correctamente (el aumento de la complejidad tampoco es lineal [pero eso es observacional y no tengo estadísticas reales que respalden esa afirmación]). Entonces, si tiene más de 1 puntero RAW, piense en envolver cada uno en su propia clase (algún tipo de puntero inteligente).

Regla de 4: si un objeto es el propietario de un puntero RAW, debe definir los siguientes 4 miembros para asegurarse de que maneja la administración de memoria correctamente:

  • Constructor
  • Copiar constructor
  • Operador de asignación
  • Destructor

La forma en que los definas dependerá de las situaciones. Pero cosas a tener en cuenta:

  • Construcción predeterminada: establezca el puntero en NULL
  • Copia del constructor: utilice el ítem Copiar e Intercambiar para proporcionar a la "Garantía de Excepción Fuerte",
  • Operador de asignación: verifica la asignación a uno mismo
  • Destructor: protege contra excepciones que se propagan fuera del destructor.

intenta leer esto.

http://www.icu-project.org/docs /papers/cpp_report/the_anatomy_of_the_assignment_operator.html

es un muy buen análisis del operador de asignación

Aquí no tengo idea de la excepción, pero voy por este camino. Imaginemos que es un envoltorio de matriz templada. 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;
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top