recientemente volví a visitar el constructor de copia, operador de asignación, copia idom de intercambio se ve aquí: What is the copy-and-swap idiom? y muchos otros lugares -constructor de copia e implementación operador de asignación opciones -
el vínculo anterior es un excelente post - pero todavía tenía unas cuantas preguntas más - Estas preguntas se responden en un montón de lugares, en stackOverflow y muchos otros sitios, pero no he visto un montón de consistencia -
1 - en caso de tener try
-catch
alrededor de las áreas donde asignamos la nueva memoria para una copia profunda en la copia contra tructor? (Lo he visto de ambas maneras)
2 - Con respecto a la herencia tanto para el constructor de copias como para el operador de asignación, ¿cuándo deberían llamarse las funciones de la clase base y cuándo deberían ser virtuales?
3 - ¿Es std::copy
la mejor manera de duplicar memoria en el constructor de copia? Lo he visto con memcpy
, y he visto otros decir memcpy
lo peor de la tierra.
Considérese el siguiente ejemplo (Gracias por todos los comentarios), que provocó algunas preguntas adicionales:
4 - ¿Hay que hacer el registro para la asignación de uno mismo? Si es así, donde
5 - Off topic pregunta, pero yo he visto intercambiado utilizado como: std::copy(Other.Data,Other.Data + size,Data);
debería ser: std::copy(Other.Data,Other.Data + (size-1),Data);
si permuta va desde 'el primer al último' y el elemento 0 se encuentra Other.Data?
6 - ¿Por qué no funciona el constructor comentado (tuve que cambiar el tamaño a mysize) - se supone que esto significa que independientemente del orden en que los escriba, el constructor siempre llamará primero al elemento de asignación?
7 - ¿Algún otro comentario sobre mi implementación? Sé que el código es inútil, pero solo intento ilustrar un punto.
class TBar
{
public:
//Swap Function
void swap(TBar &One, TBar &Two)
{
std::swap(One.b,Two.b);
std::swap(One.a,Two.a);
}
int a;
int *b;
TBar& operator=(TBar Other)
{
swap(Other,*this);
return (*this);
}
TBar() : a(0), b(new int) {} //We Always Allocate the int
TBar(TBar const &Other) : a(Other.a), b(new int)
{
std::copy(Other.b,Other.b,b);
*b = 22; //Just to have something
}
virtual ~TBar() { delete b;}
};
class TSuperFoo : public TBar
{
public:
int* Data;
int size;
//Swap Function for copy swap
void swap (TSuperFoo &One, TSuperFoo &Two)
{
std::swap(static_cast<TBar&>(One),static_cast<TBar&>(Two));
std::swap(One.Data,Two.Data);
std::swap(One.size,Two.size);
}
//Default Constructor
TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[mysize]) {}
//TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[size]) {} *1
//Copy Constructor
TSuperFoo(TSuperFoo const &Other) : TBar(Other), size(Other.size), Data(new int[Other.size]) // I need [Other.size]! not sizw
{
std::copy(Other.Data,Other.Data + size,Data); // Should this be (size-1) if std::copy is First -> Last? *2
}
//Assignment Operator
TSuperFoo& operator=(TSuperFoo Other)
{
swap(Other,(*this));
return (*this);
}
~TSuperFoo() { delete[] Data;}
};
Gracias - Actualizado con el ejemplo – MikeyG