2012-06-23 32 views
6

Tôi đang đọc C++ Primer, 3rd Ed (Lippman và Lajoie) và nó nói rằng khi một vector cần được phân bổ lại để tạo không gian cho nhiều phần tử được thêm vào với push_back(), các phần tử được sao chép trong không gian mới và sau đó destructor được gọi là trên các yếu tố cũ. Tôi đang bối rối về lý do tại sao điều này là cần thiết - tại sao dữ liệu không thể được sao chép bit-cho-bit? Tôi giả định rằng câu trả lời phải làm với phân bổ bộ nhớ động, nhưng dòng lập luận hiện tại của tôi là ngay cả khi các phần tử vectơ xử lý bộ nhớ động, dữ liệu thực sự được lưu trữ trong các phần tử sẽ là con trỏ, có nghĩa là sao chép bit sẽ giữ nguyên vị trí mà chúng trỏ đến và sẽ không trình bày bất kỳ vấn đề nào. Tôi có thể thấy cách định vị lại bộ nhớ được cấp phát động mà các phần tử trỏ đến sẽ là một vấn đề, vì nó sẽ làm mất hiệu lực con trỏ, nhưng theo như tôi có thể nói thì vị trí lại vectơ sẽ không có lý do để làm điều đó.C++: Phân bổ lại vector tự động gọi các nhà xây dựng sao chép? Tại sao?

Ai đó có thể cho tôi một ví dụ đơn giản về một lớp không được di chuyển từng chút một không?

+2

Kịch bản trong đó hàm tạo/hủy đăng ký/hủy đăng ký địa chỉ của lớp với đối tượng cha mẹ xuất hiện trong đầu. –

+1

Kịch bản mà loại không phải là _trivially copyable_ đến với tâm trí. –

+1

ta.spot.is có một ví dụ vững chắc, mặc dù tôi sẽ không gọi mọi đối tượng đăng ký là "cha mẹ". Một cách riêng biệt, một số lớp có thể giữ con trỏ đến các thành viên dữ liệu riêng của chúng - ví dụ, để mô hình một số trạng thái phương thức, nói rằng một số hoạt động trong tương lai sẽ ảnh hưởng đến thành viên cụ thể đó hoặc có một trình vòng lặp vào một vector nội bộ. –

Trả lời

7

Đây là có lẽ là đơn giản nhất (mà đúng hơn là giả tạo) ví dụ:

class foo 
{ 
    int i; 
    int* pi; // always points to i 
}; 

Ở đây, các nhà xây dựng bản sao sẽ duy trì bất biến mà pi điểm để i. Bản thân trình biên dịch sẽ không thể tự mình tìm ra mối quan hệ này, do đó cần phải gọi hàm tạo bản sao.

4

Ai đó có thể cho tôi ví dụ đơn giản về một lớp không được di chuyển từng chút một?

Bằng cách tiêu chuẩn, làm một memcpy trên bất kỳ lớp đó không phải là a POD in C++03 (or trivially copyable in C++11) sẽ đủ điều kiện. memcpy ing non-PODs (hoặc non-trivially copyable) gọi hành vi không xác định; do đó một bản sao thực tế (hoặc trong C++ 11, di chuyển) constructor phải được sử dụng.

Vì vậy, std::vectorchính nó áp dụng, vì đây không phải là loại POD (và trong C++ 11, không thể sao chép được một cách không đáng kể).

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