2015-12-14 22 views
5

Perché il distruttore del nodo viene chiamato una sola volta invece di 5 volte nel codice qui sotto?Vector of smart pointers chiamata del distruttore

#include <iostream> 
#include <vector> 
#include <memory> 

struct Node { 
    ~Node() {std::cout << "Node destructor called.\n";} 
}; 

void foo() { 
    std::vector<std::shared_ptr<Node>> nodes(5, std::make_shared<Node>()); 
} 

int main() { 
    foo(); 
    std::cout << "foo() ended.\n"; 
} 
+0

@prestokeys: Sembra che si erano in qualche modo aspettate il codice di agire come un * * macro che duplica testualmente l'espressione argomento in ogni costruttore elemento. Ma non è questo il caso; l'espressione viene valutata * una volta * e associata al parametro costruttore. Immagino che questa sia la differenza tra la valutazione dell'espressione e le macro, ed è per questo che è ancora bello avere dei macro. Lingue come Scheme ti permettono di farlo correttamente. –

risposta

12

vostro vettore contiene cinque copie del puntatore condiviso originale, tutti accomunati proprietà del un unico pointee.

Per creare cinque oggetti separati, ciascuno di proprietà di un puntatore condiviso, scrivere in questo modo:

std::vector<std::shared_ptr<Node>> nodes; 
for (int i = 0; i != 5; ++i) nodes.push_back(std::make_shared<Node>()); 
1

Kerrek SB spiegato bene la situazione, ma per fare ciò che si vuole fare in modo diverso, si potrebbe anche la std::generate_n algoritmo:

std::vector<std::shared_ptr<Node>> nodes; 
std::generate_n(
    std::back_inserter(nodes), 
    5, 
    std::make_shared<Node>); 

Questo è più lungo le linee di quello che si pensava che stavi facendo in origine.

Oppure, simile:

std::vector<std::shared_ptr<Node>> nodes(5); 
std::generate(nodes.begin(), nodes.end(), std::make_shared<Node>);