2015-12-14 7 views
5

Warum wird der Node-Destruktor nur einmal statt 5 mal im folgenden Code aufgerufen?Vector of Smart Pointer Destructor Anruf

#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: Es scheint, dass Sie irgendwie der Code wie ein * Makro * zu handeln erwarteten, die textlich das Argument Ausdruck in jedem Elementkonstruktor dupliziert. Aber das ist nicht der Fall; Der Ausdruck wird * einmal * ausgewertet und an den Konstruktorparameter gebunden. Ich denke, das ist der Unterschied zwischen der Auswertung von Ausdrücken und Makros, und deshalb ist es immer noch schön, Makros zu haben. Sprachen wie Scheme lassen Sie das richtig machen. –

Antwort

12

Ihr Vektor enthält fünf Kopien des ursprünglichen freigegebenen Zeiger, die alle teilen das Eigentum an der einem einzigen pointee.

fünf separate Objekte zu erstellen, die jeweils von einem gemeinsamen Zeiger im Besitz, schreiben Sie es wie folgt aus:

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

Kerrek SB die Situation gut erklärt, aber zu tun, was man in einer anderen Art und Weise tun möchten, können Sie auch der std::generate_n Algorithmus:

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

Dies ist mehr entlang den Linien von dem, was Sie dachten, Sie ursprünglich taten.

Oder ähnlich:

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