Theo như tôi hiểu tiêu chuẩn (mặc dù tôi thực sự không thể đặt tên cho một tham chiếu), việc cài đặt vùng chứa và phân bổ bộ nhớ đã cố ý được tách ra vì lý do chính đáng. Vì vậy, bạn có các cuộc gọi riêng biệt, riêng biệt cho
constructor
để tự tạo vùng chứa
reserve()
phân bổ trước một khối bộ nhớ lớn thích hợp để chứa ít nhất (!) một số lượng đối tượng nhất định
Và điều này rất có ý nghĩa. Quyền duy nhất để tồn tại reserve()
là cho bạn cơ hội để viết mã xung quanh việc tái phân bổ có thể tốn kém khi phát triển vectơ. Để trở nên hữu ích, bạn phải biết số lượng đồ vật cần lưu trữ hoặc ít nhất cần phải có khả năng phỏng đoán có học. Nếu điều này không được cung cấp, tốt hơn bạn nên tránh xa reserve()
vì bạn sẽ chỉ thay đổi sự phân bổ lại cho bộ nhớ lãng phí.
Vì vậy, tổng hợp tất cả lại với nhau:
- Tiêu chuẩn cố ý không chỉ định một phương thức khởi tạo cho phép bạn cấp phát trước một khối bộ nhớ cho một số đối tượng cụ thể (điều này ít nhất sẽ tốt hơn so với việc cấp phát một "cái gì đó" cụ thể, cố định dưới mui xe).
- Phân bổ không được ngầm hiểu. Vì vậy, để phân bổ trước một khối, bạn cần thực hiện một cuộc gọi riêng
reserve()
và khối này không cần phải ở cùng một địa điểm xây dựng (tất nhiên có thể / nên muộn hơn, sau khi bạn biết về kích thước cần thiết để chứa)
- Vì vậy, nếu một vectơ luôn định vị trước một khối bộ nhớ có kích thước được xác định thì điều này sẽ làm hỏng công việc dự định của nó
reserve()
, phải không?
- Lợi thế của việc định vị trước một khối là gì nếu STL tự nhiên không thể biết mục đích dự định và kích thước dự kiến của một vectơ? Nó sẽ khá vô nghĩa, nếu không muốn nói là phản tác dụng.
- Giải pháp thích hợp thay vào đó là phân bổ và triển khai khối cụ thể với khối đầu tiên
push_back()
- nếu chưa được phân bổ rõ ràng trước đó reserve()
.
- Trong trường hợp phân bổ lại cần thiết, việc tăng kích thước khối cũng là việc thực hiện cụ thể. Các triển khai vectơ mà tôi biết bắt đầu với sự gia tăng kích thước theo cấp số nhân nhưng sẽ giới hạn tốc độ tăng ở một mức tối đa nhất định để tránh lãng phí một lượng lớn bộ nhớ hoặc thậm chí thổi bay nó.
Tất cả điều này chỉ hoạt động đầy đủ và thuận lợi nếu không bị làm phiền bởi một hàm tạo cấp phát. Bạn có các giá trị mặc định hợp lý cho các tình huống phổ biến có thể được ghi đè theo yêu cầu bởi reserve()
(và shrink_to_fit()
). Vì vậy, ngay cả khi tiêu chuẩn không nêu rõ ràng như vậy, tôi khá chắc chắn rằng giả định rằng một vectơ mới được xây dựng không phân bổ trước là một đặt cược khá an toàn cho tất cả các triển khai hiện tại.