W języku C++, gdy klasy zawierają dynamicznie przydzielane dane, zwykle rozsądnie jest zdefiniować jawnie konstruktora kopii, operatora = i destruktora. Ale działanie tych specjalnych metod nakłada się. Bardziej konkretnie operator = zwykle najpierw robi pewne zniszczenia, a następnie radzi sobie podobnie jak w konstruktorze kopiującym.Unikaj powtarzania tego samego kodu w konstruktorze kopiującym i operatorze =
Moje pytanie brzmi: jak napisać to najlepiej, bez powtarzania tych samych linii kodu i bez potrzeby wykonywania niepotrzebnej pracy procesora (jak niepotrzebne kopiowanie).
Zazwyczaj otrzymuję dwie metody pomocy. Jeden do budowy i jeden do zniszczenia. Pierwszy jest wywoływany zarówno z konstruktora kopiowania, jak i operatora =. Drugi jest używany przez destruktor i operator =.
Oto przykładowy kod:
template <class T>
class MyClass
{
private:
// Data members
int count;
T* data; // Some of them are dynamicly allocated
void construct(const MyClass& myClass)
{
// Code which does deep copy
this->count = myClass.count;
data = new T[count];
try
{
for (int i = 0; i < count; i++)
data[i] = myClass.data[i];
}
catch (...)
{
delete[] data;
throw;
}
}
void destruct()
{
// Dealocate all dynamicly allocated data members
delete[] data;
}
public: MyClass(int count) : count(count)
{
data = new T[count];
}
MyClass(const MyClass& myClass)
{
construct(myClass);
}
MyClass& operator = (const MyClass& myClass)
{
if (this != &myClass)
{
destruct();
construct(myClass);
}
return *this;
}
~MyClass()
{
destruct();
}
};
Czy to jeszcze jest prawidłowy? A czy dobrze jest podzielić kod w ten sposób?
+1, ponieważ pytanie pomogło zwiększyć moją świadomość. Wygląda to na coś, co napisałbym przed przeczytaniem odpowiedzi. – ToolmakerSteve
Hmm, rzadko mam zduplikowany kod w obu, ponieważ oba robią zupełnie różne rzeczy: jeden z nich inicjuje, jeden przypisuje ... – PlasmaHH
jego "głęboką kopię" charakteru jego projektu klasowego, który prowadzi do powielania. – ToolmakerSteve