2015-12-14 15 views
5

Tại sao các Node destructor được gọi chỉ một lần thay vì 5 lần trong mã dưới đây?Vector của con trỏ thông minh destructor gọi

#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: Có vẻ như bạn đã bằng cách nào đó mong mã để hành động như một * vĩ mô * rằng bản văn bản sao biểu thức đối số vào mỗi nhà xây dựng phần tử. Nhưng đó không phải là trường hợp; biểu thức được đánh giá * một lần * và liên kết với tham số hàm tạo. Tôi đoán đó là sự khác biệt giữa đánh giá biểu thức và macro, và đó là lý do tại sao nó vẫn tốt để có macro. Các ngôn ngữ như Scheme cho phép bạn làm điều đó đúng cách. –

Trả lời

12

vector của bạn có chứa năm bản của con trỏ chia sẻ ban đầu, tất cả các quyền sở hữu chung của một pointee đơn.

Để tạo năm đối tượng riêng biệt, mỗi thuộc sở hữu của một con trỏ chia sẻ, hãy viết nó như thế này:

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

Kerrek SB giải thích tình hình tốt, nhưng để làm những gì bạn muốn làm theo một cách khác, bạn có thể cũng là thuật toán std::generate_n:

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

Đây là những gì bạn nghĩ ban đầu.

Hoặc tương tự:

std::vector<std::shared_ptr<Node>> nodes(5); 
std::generate(nodes.begin(), nodes.end(), std::make_shared<Node>); 
Các vấn đề liên quan