Regla de tres en C++

Esta regla básicamente establece que si una clase define uno (o más) de los siguientes, debe definir explícitamente los tres, que son:

Ahora intentemos entender por qué. 
Los constructores predeterminados y los operadores de asignación hacen una copia superficial y creamos nuestro propio constructor y operadores de asignación cuando necesitamos realizar una copia profunda (por ejemplo, cuando una clase contiene punteros que apuntan a recursos asignados dinámicamente).

Primero, ¿qué hace un destructor? Contiene código que se ejecuta cada vez que se destruye un objeto. Solo afectar el contenido del objeto sería inútil. Un objeto en proceso de destrucción no puede sufrir cambios. Por lo tanto, el destructor afecta el estado del programa como un todo. 

Ahora, supongamos que nuestra clase no tiene un constructor de copias. Al copiar un objeto, se copiarán todos sus miembros de datos en el objeto de destino. En este caso, cuando el objeto se destruye, el destructor se ejecuta dos veces. Además, el destructor tiene la misma información para cada objeto que se destruye. En ausencia de un constructor de copia definido apropiadamente, el destructor se ejecuta dos veces cuando solo debería ejecutarse una vez. Esta ejecución duplicada es una fuente de problemas.

A continuación se muestra un ejemplo de codificación: 

C++

// In the below C++ code, we have created
// a destructor, but no copy constructor
// and no copy assignment operator.
class Array
{
private:
    int size;
    int* vals; 
  
public:
    ~Array();
    Array( int s, int* v );
};
  
Array::~Array()
{
   delete vals;
   vals = NULL;
}
  
Array::Array( int s, int* v )
{
    size = s;
    vals = new int[ size ];
    std::copy( v, v + size, vals );
}
  
int main()
{
   int vals[ 4 ] = { 11, 22, 33, 44 };
   Array a1( 4, vals );
 
   // This line causes problems.
   Array a2( a1 );
 
   return 0;
}

En el ejemplo anterior, una vez que el programa sale del alcance, se llama al destructor de clases, no una sino dos veces. Primero por deleción de a1 y luego de a2. El constructor de copia predeterminado hace una copia del puntero vals y no le asigna memoria. Por lo tanto, al eliminar a1, el destructor libera vals . Todos los valores posteriores que contienen instancias cuando el destructor intenta eliminarlos hacen que el programa se bloquee, ya que los valores ya no existen.

Esto es similar en el caso del operador de asignación de copias . Si una clase no tiene un operador de asignación definido explícitamente, se producirá una asignación implícita de todos los miembros de datos del origen a los miembros de datos correspondientes del destino. Con todo, crea una copia, que nuevamente es el mismo problema definido anteriormente.

Referencias:

Este artículo es una contribución de Nihar Ranjan Sarkar . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *