2013-07-24 22 views
8

Da cplusplus.com:C++ costruttore di copia con i membri shared_ptr

Raramente ci si imbatte in una classe che non contiene i puntatori prime ancora il costruttore di copia di default non è sufficiente. Un esempio di questo è quando si dispone di un oggetto conteggiato con riferimento. boost :: shared_ptr <> è l'esempio .

Qualcuno può elaborare su questo? Se abbiamo una classe contenente uno boost::shared_ptr, non otterremo una copia costruita quando la classe avrà una copia costruita - e quindi il costruttore shared_ptr non farà la cosa giusta e aumenterà il conteggio dei riferimenti? Il seguente codice, ad esempio, le copie Inner correttamente - il motivo per cui non sarebbe questo lavoro per 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

Forse non sei stato inciampato dai doppi negativi mancanti che non sono in quella dichiarazione? –

+0

Scordatelo, sono solo bollocks. Fai finta di non aver parlato di shared_ptr. Immagino che questo sia ancora un altro dei motivi per cui cplusplus.com è così insultato. –

+0

Quindi, per fare una domanda migliore allora. Quando la gente dice "il costruttore di copie predefinito fa una copia superficiale", significa "chiama i costruttori di copia di tutti i membri a sua volta" o "semplicemente memcpy() nell'istanza della classe" –

risposta

12

Il costruttore di copie predefinito utilizzerà il costruttore di copie per ogni variabile membro o copia bit per i tipi predefiniti.

Se si utilizza un puntatore condiviso di qualche tipo, il costruttore di copie incrementerà il conteggio condiviso e sia l'originale che i nuovi oggetti punteranno allo stesso oggetto.

In alcuni casi, questo è ciò che si desidera; copiare il puntatore e gestire correttamente il conteggio dei riferimenti in modo che la risorsa possa essere liberata quando non viene più utilizzata.

Il contesto dell'articolo citato sta copiando un intero oggetto. In questo caso, ci si aspetta che ogni oggetto abbia una propria copia dei suoi sottooggetti e non condivida i sottooggetti con altre istanze. In questo caso, shared_ptr è probabilmente la scelta sbagliata e sicuramente non copierà in profondità i sottooggetti.

Il paragrafo è mal formulato, ma sono sicuro che stia parlando di deep-copy ma dicendo che lo shared_ptr non fornirà quella deep-copy. Questo è vero, perché non è quello per cui è stato progettato.

1

Credo che significa che la nuova classe farà riferimento alla risorsa della vecchia classe, in cui ci si potrebbe aspettare una copia a? essere fatto della vecchia risorsa per la nuova classe, come accadrebbe se fosse un membro a pieno titolo della classe. O è accettabile, dipende da cosa stai facendo.

Ad esempio, se si copia un cane e un cane ha un osso, il nuovo cane ottiene il proprio osso o condivide l'osso originale?

+0

Questo è ciò che descrive il paragrafo precedente nell'articolo collegato; se l'oggetto contiene un puntatore non elaborato a una risorsa gestita (che di solito è una pessima idea), allora sarà necessario un costruttore di copie per gestirlo. Il paragrafo citato è semplicemente privo di senso. –

+0

Se si desidera che l'oggetto copiato abbia una copia della risorsa originale e non la condivida, è necessario un costruttore di copia quando si utilizza shared_ptr –

+0

. Vedo. Sì, forse l'autore sta cercando di dire che avrai bisogno di un costruttore di copie se usi un puntatore condiviso quando non vuoi la sua semantica condivisa. È piuttosto una cosa strana da fare però. –

5

Qualcuno può elaborare su questo?

Non proprio; è senza senso.

Se abbiamo una classe che contiene un boost::shared_ptr, non sarà che arrivare copia costruito quando la classe viene costruita la copia - e quindi il costruttore shared_ptr non farà la cosa giusta e aumentare il numero di riferimento?

Proprio così. shared_ptr è progettato correttamente con semantica della copia valida, quindi non è necessario gestirlo in modo particolare quando si copia un oggetto di classe contenente uno.

Probabilmente, l'autore intendeva dire che se si desidera copiare, anziché condividere, l'oggetto condiviso, è necessario un costruttore di copie per crearne uno nuovo. Tuttavia, è piuttosto strano utilizzare shared_ptr se non si desidera condividere la proprietà.

Problemi correlati