unique_ptr
nie można go kopiować, można go tylko przenosić.
Wpłynie to bezpośrednio na Test, który w twoim drugim przykładzie jest również możliwy do przeniesienia i nie do skopiowania.
W rzeczywistości dobrze jest, gdy używasz, unique_ptr
który chroni cię przed dużym błędem.
Na przykład głównym problemem związanym z pierwszym kodem jest to, że wskaźnik nigdy nie jest usuwany, co jest naprawdę, bardzo złe. Powiedzmy, że możesz to naprawić przez:
class Test
{
int* ptr; // writing this in one line is meh, not sure if even standard C++
Test() : ptr(new int(10)) {}
~Test() {delete ptr;}
};
int main()
{
Test o;
Test t = o;
}
To też jest złe. Co się stanie, jeśli skopiujesz Test
? Będą dwie klasy, które będą miały wskaźnik wskazujący na ten sam adres.
Kiedy jeden Test
zostanie zniszczony, zniszczy również wskaźnik. Kiedy twoja sekunda Test
zostanie zniszczona, spróbuje również usunąć pamięć za wskaźnikiem. Ale został już usunięty i otrzymamy zły błąd w czasie wykonywania dostępu do pamięci (lub niezdefiniowane zachowanie, jeśli mamy pecha).
Zatem właściwym sposobem jest albo zaimplementowanie konstruktora kopiującego, jak i operatora przypisania kopiującego, aby zachowanie było jasne i można było utworzyć kopię.
unique_ptr
wyprzedza nas tutaj. Ma znaczenie semantyczne: „ Jestem unique
, więc nie możesz mnie tak po prostu skopiować. ” Tak więc, zapobiega to błędowi implementacji dostępnych operatorów.
Możesz zdefiniować konstruktora kopiującego i operatora przypisania kopii dla specjalnego zachowania, a kod będzie działał. Ale słusznie (!) Jesteś do tego zmuszony.
Morał tej historii: zawsze używaj unique_ptr
w tego rodzaju sytuacjach.