La razón más común para definir explícitamente un operador de asignación es admitir "propiedad remota", básicamente, una clase que incluye uno o más punteros y posee los recursos a los que se refieren esos punteros. En tal caso, normalmente necesita definir la asignación, la copia (es decir, el constructor de copia) y la destrucción. Hay tres estrategias principales para estos casos (clasificados por la disminución de la frecuencia de uso):
- copia profunda
- referencia contando
- La transferencia de propiedad
copia profunda significa la asignación de un nuevo recurso para el objetivo de la asignación/copia. P.ej., una clase de cadena tiene un puntero al contenido de la cadena; cuando lo asigne, la asignación asigna un nuevo búfer para mantener el nuevo contenido en el destino y copia los datos del origen al búfer de destino. Esto se utiliza en la mayoría de las implementaciones actuales de varias clases estándar, como std::string
y std::vector
.
Recuento de referencias usado es bastante común también. Muchas (¿la mayoría?) Implementaciones más antiguas de std::string
utilizan el recuento de referencias. En este caso, en lugar de asignar y copiar los datos para la cadena, simplemente incrementó un conteo de referencia para indicar el número de objetos de cadena que hacen referencia a un buffer de datos en particular. Solo asignó un nuevo búfer cuando/si el contenido de una cadena se modificó por lo que debe diferir de los demás (es decir, utilizó la copia en escritura). Sin embargo, con multiprocesamiento, debe sincronizar el acceso al recuento de referencias, que a menudo tiene un impacto grave en el rendimiento, por lo que en el código más reciente esto es bastante inusual (se usa principalmente cuando algo almacena así que mucha información que puede desperdiciar un poco del tiempo de CPU para evitar dicha copia).
La transferencia de propiedad es relativamente inusual. Es lo que se hace por std::auto_ptr
. Cuando asigna o copia algo, la fuente de la asignación/copia se destruye básicamente: los datos se transfieren de uno a otro. Esto es (o puede ser) útil, pero la semántica es lo suficientemente diferente de la asignación normal que a menudo es contradictorio. Al mismo tiempo, en las circunstancias adecuadas, puede proporcionar una gran eficiencia y simplicidad. C++ 0x hará que la transferencia de propiedad sea considerablemente más manejable agregando un tipo unique_ptr
que lo haga más explícito, y también agregue referencias rvalue, que facilitan la implementación de la transferencia de propiedad para una clase bastante grande de situaciones donde puede mejorar el rendimiento sin dando lugar a una semántica que sea visiblemente contradictoria.
Volviendo a la pregunta original, sin embargo, si no tiene propiedad remota para empezar, es decir, su clase no contiene punteros, es probable que no deba definir explícitamente un operador de asignación. (o dtor o copiar ctor). Un error del compilador que impidió el funcionamiento de los operadores de asignación definidos impidió pasar una gran cantidad de pruebas de regresión.
Incluso si de alguna manera se liberara, su defensa sería simplemente no usarlo. No hay espacio real para la pregunta de que tal lanzamiento sería reemplazado en cuestión de horas. Con un proyecto existente mediano a grande, no desea cambiar a un compilador hasta que haya estado en uso durante un tiempo en cualquier caso.
Tenga en cuenta que su ejemplo de código no invoca al operador de asignación de copias. Invoca el constructor de copia. El '=' aquí no es una tarea, es una inicialización. Necesitaría algo similar a 'CalibDataSet dataSetB; dataSetB = datasetA; 'para invocar el operador de asignación de copia. –
Bueno, eso depende. Mostrar la definición de CalibDataSet. ¿Administra el recurso? –
Regla de oro: si todo en su clase puede y debe ser copiado por 'a.thing = b.thing', entonces el operador autogenerado probablemente esté bien. –