2013-07-24 9 views
8

Od cplusplus.com:C++ skopiować konstruktora z członkami shared_ptr

Rzadko można natknąć klasy, która nie zawiera surowych wskaźników jeszcze konstruktor domyślny kopia nie jest wystarczające. Przykładem tego jest , gdy mamy obiekt zliczający referencje. boost :: shared_ptr <> to przykład: .

Czy ktoś może to wyjaśnić? Jeśli mamy klasę zawierającą boost::shared_ptr, czy nie otrzymamy kopii skonstruowanej, gdy klasa zostanie skonstruowana w ten sposób - a zatem czy konstruktor shared_ptr nie zrobi czegoś właściwego i nie zwiększy liczby odwołań? Poniższy kod, na przykład kopie Inner właściwie - dlaczego nie ta praca dla shared_ptr:

#include <iostream> 
using namespace std; 

class Inner 
{ 
public: 
Inner() { cout << "inner default constructed" << endl;} 
Inner(const Inner& other) { cout << "inner properly copied" << endl;} 
}; 

class Outer 
{ 
Inner i; 
}; 

int main() { Outer o; Outer p(o); return 0;} 
+8

Może nie dałeś się zaskoczyć brakiem podwójnych negatywów, których nie ma w tym stwierdzeniu? –

+0

Zapomnij o tym, to tylko bzdury. Udawaj, że nie wspominał o shared_ptr. Sądzę, że jest to jeszcze jeden z powodów, dla których cplusplus.com jest tak obrażany. –

+0

Więc zadaj lepsze pytanie. Kiedy ludzie mówią, że "domyślny konstruktor kopiowania wykonuje płytką kopię", oznacza to "wywołuje konstruktory kopiujące wszystkich członków po kolei" lub "po prostu robi memcpy() w instancji klasy" –

Odpowiedz

12

Domyślny konstruktor kopiowania użyje konstruktora kopiowania dla każdej zmiennej składowej lub kopii bitowej dla typów wbudowanych.

Jeśli używasz współdzielonego wskaźnika jakiegoś rodzaju, konstruktor kopiowania zwiększy dzieloną liczbę i zarówno oryginalny, jak i nowy obiekt wskaże ten sam obiekt.

W niektórych przypadkach jest to, czego chcesz; kopiowanie wskaźnika i poprawne zarządzanie licznikiem odwołań, dzięki czemu zasób może zostać zwolniony, gdy nie jest już używany.

Kontekst cytowanego artykułu dotyczy kopiowania całego obiektu. W tym przypadku każdy obiekt powinien mieć własną kopię swoich podobiektów, a nie współużytkować podobiektów z innymi instancjami. W tym przypadku, shared_ptr jest prawdopodobnie złym wyborem iz pewnością nie będzie głęboko kopiować podobiektów.

Paragraf jest źle sformułowany, ale jestem pewien, że mówi o głębokim kopiowaniu, ale mówi, że shared_ptr nie dostarczy tej głębokiej kopii. Co prawda, ponieważ nie jest to tym, do czego jest przeznaczony.

1

Myślę, że to oznacza, że ​​nowa klasa będzie odnosić się do starej klasy jest zasobem, gdzie można spodziewać się kopię? być zrobione ze starego zasobu dla nowej klasy, jak to by się stało, gdyby był pełnym członkiem klasy. Albo jest do zaakceptowania - zależy to od tego, co robisz.

Na przykład, jeśli kopiujesz psa, a pies ma kość, czy nowy pies otrzymuje własną kość, czy też ma tę samą kość?

+0

Tak opisuje poprzedni akapit w połączonym artykule; jeśli obiekt zawiera surowy wskaźnik do zasobu, którym zarządza (co zwykle jest bardzo złym pomysłem), to potrzebujesz konstruktora kopiowania, aby sobie z tym poradzić. Cytowany akapit jest po prostu bełkotem. –

+0

Jeśli chcesz, aby skopiowany obiekt miał kopię oryginalnego zasobu i nie udostępniał go, będziesz potrzebować konstruktora kopiowania podczas korzystania z shared_ptr –

+0

Widzę. Tak, być może autor próbuje powiedzieć, że będziesz potrzebował konstruktora kopiowania, jeśli użyjesz współdzielonego wskaźnika, gdy nie chcesz mieć jego wspólnej semantyki. To jednak dziwna rzecz. –

5

Czy ktoś może to wyjaśnić?

Niezupełnie; to bełkot.

Jeśli mamy klasę zawierającą boost::shared_ptr, że nie będzie się kopia skonstruowany gdy klasa dostaje kopia zbudowane - a co za tym idzie nie będzie konstruktor shared_ptr zrobić dobry uczynek i zwiększyć liczbę odwołań?

Zgadza się. shared_ptr jest poprawnie zaprojektowany z prawidłową semantyką kopiowania, więc nie ma potrzeby zajmowania się nim specjalnie podczas kopiowania obiektu klasy zawierającego jeden.

Możliwe, autor miał na myśli, że jeśli chcesz skopiować, a nie udostępnić obiekt współdzielony, musisz utworzyć konstruktora kopii, aby utworzyć nowy. Jednak, jeśli nie chcesz mieć własności współdzielonej, to raczej dziwne jest używanie numeru shared_ptr.

Powiązane problemy