2012-05-31 10 views
6

Immaginate un class C che abbia una variabile membro m_MyList di tipo std::vector in cui voglio memorizzare oggetti di tipo MyClass. C ha due funzioni che aggiungono o rimuovono oggetti in m_MyList. m_MyList dovrebbe anche essere reso accessibile per i consumatori di C in quanto devono leggere la raccolta di oggetti MyClass. Il lettore esterno della raccolta non avrà alcun mezzo per modificare la raccolta, pertanto gli oggetti MyClass appartengono solo allo C.Devo usare std :: unique_ptr <T> in una variabile membro std :: vector nella mia classe?

Ora la mia domanda: In stile C++ 11, qual è la T migliore da memorizzare nel vettore? Le possibilità sembrano essere:

  • std::vector<MyClass>
  • std::vector<MyClass*>
  • std::vector<unique_ptr<MyClass>>, utilizzando std:move per spingere il unique_ptr nella vector
+3

La soluzione 'unique_ptr' non ti compra davvero nulla, a meno che gli oggetti non siano copiabili. La versione raw pointer è decisamente dannosa. Basta andare per la soluzione semplice – jalf

+0

Quanto è grande un oggetto 'MyClass' e quanti ne hai intenzione di memorizzare? Ci saranno molti singoli inserimenti? – RedX

risposta

13

Se gli MyClass oggetti sono di proprietà di C, allora il miglior l'opzione sarebbe la più semplice:

std::vector<MyClass> 

L'unica ragione per cui ho potuto vedere per utilizzare std::unique_ptrs qui è se è necessario mantenere puntatori a una classe di base per il polimorfismo. In questo caso, unique_ptrs ha lo scopo di liberare risorse dopo la distruzione del vettore. Ma l'interfaccia C non dovrebbe trasferire la proprietà ai client.

+5

'MyClass' potrebbe essere un oggetto che è costoso da spostare/copiare. L'uso di un puntatore ti consente di ridimensionare il vettore senza dover copiare molta memoria. –

+1

@ edA-qamort-ora-y è vero, ma è indipendente dalla proprietà e dai client e così via, quindi ho ritenuto che la considerazione fosse oltre lo scopo della domanda. – juanchopanza

+1

L'altro motivo per utilizzare qualsiasi tipo di riferimento come membro di una classe è assicurarsi che l'intestazione non esponga i dettagli di quei membri, mentre il file di unità (cpp) ne è a conoscenza. In realtà è buono per l'isolamento. Qui il vettore richiede che MyClass sia definito prima che il membro sia definito. Quindi devi includere il codice MyClass. In alcuni casi, non lo vuoi. Detto questo, ha una memoria diversa e costi di gestione, quindi la scelta è molto specifica del contesto. – Klaim

11

I puntatori grezzi (std::vector<MyClass*>) non sono corretti se C possiede gli oggetti. Gli altri due sono abbastanza simili con i seguenti compromessi:

  • std::vector<MyClass> - richiede MyClass essere copiabile e/o spostare-grado
  • std::vector<unique_ptr<MyClass>> - richiede (supplementari) allocazioni dinamiche

Il il tipo di operazioni eseguite sul contenitore può anche essere rilevante. Per fare un esempio estremo, se MyClass è grande e il contenitore viene ripetutamente mescolato, unique_ptr sarebbe la scelta migliore.

+0

Ogni elemento di un 'std :: vector' viene inserito nell'archivio gratuito, quindi pronunciare" richiede allocazioni dinamiche "come se fosse una brutta cosa è una specie di termine improprio qui ... – rubenvb

+2

@rubenvb: il vettore richiede solo un'allocazione dinamica alla volta (o brevemente 2 durante la riallocazione). Quindi non richiede allocazioni dinamiche ;-) Se 'MyClass' è abbastanza piccolo, noterai alla fine la differenza. Suppongo che potrebbe essere meglio dire "richiede un sovraccarico maggiore nelle allocazioni dinamiche". È una brutta cosa se stai scrivendo un codice in più con l'unico scopo di sprecare memoria. Potrebbe * essere una brutta cosa se 'MyClass' non è costruibile, e si introducono allocazioni dinamiche in luoghi che altrimenti non accadrebbero, introducendo quindi eccezioni. –

+0

L'allocazione dinamica di ogni singolo oggetto non solo richiede più memoria, aumenta la frammentazione e causa un numero maggiore di errori nella cache dei dati. Nella maggior parte del codice, sarà del tutto inosservabile, ma come dice Steve - non digitare più per rendere il codice leggermente peggiore. –

Problemi correlati