2016-10-29 16 views
14

Vui lòng xem xét mã này:Bắt xung quanh sao chép ngữ nghĩa trong C++

class A 
{ 

}; 

int main() 
{ 
    std::vector<A> test; 
    test.push_back(A()); 
} 

Các constructor và destructor sẽ được gọi là hai lần, cũng nhớ sẽ được phân bổ hai lần và đối tượng sẽ được sao chép, bây giờ không chỉ là nguy cơ tiềm tàng cho hiệu suất nó cũng có thể dẫn đến lỗi thời gian chạy, đặc biệt nếu có một số dọn dẹp xảy ra trong destructor. Cách tôi thường nhận được xung quanh việc này là chỉ cần tạo một vectơ của con trỏ thay thế:

std::vector<A*> test; 
test.push_back(new A()); 

Câu hỏi của tôi là hai lần, thực tiễn phổ biến này và là thực hành tốt? đây có phải là cách tốt hơn không? Nếu điều này trở thành một bản dupe, vui lòng cho tôi biết và tôi sẽ đóng câu hỏi, nhưng tôi không thể tìm thấy bất kỳ điều gì khi tìm kiếm.

+7

Thực tiễn phổ biến là * không * sử dụng con trỏ. Và * không * sử dụng con trỏ là thực hành tốt. Và nó sẽ là thực hành tốt hơn nếu bạn không sử dụng con trỏ và thực hiện một * constructor * phong trào. –

+0

vẫn còn, 'std :: vector kiểm tra' là cần thiết khi đa hình được yêu cầu trong danh sách (và B là lớp cơ sở). Nhưng chỉ ở đây ... và tôi đồng ý rằng điều đó không tốt cho rò rỉ bộ nhớ/giải phóng đôi. –

+0

Cách tốt hơn là triển khai một hàm tạo di chuyển cho 'B'. –

Trả lời

24

Sử dụng emplace_back.

std::vector<A> test; 
test.emplace_back(); 
//test.emplace_back(constructor, parameters); 

Bằng cách này, A sẽ được xây dựng tại chỗ, vì vậy sẽ không có bản sao hoặc di chuyển nào xảy ra.

Chỉnh sửa: Để làm rõ các nhận xét về câu hỏi - Không, điều này sẽ không thay đổi từ push_back nếu bạn tạm thời chuyển nó. Ví dụ,

test.emplace_back(A{}); 

Will, trong C++ 11, gây ra một Tồn tại tạm thời được xây dựng, di chuyển và phá hủy, như nếu bạn sử dụng push_back.

Các vấn đề liên quan