2015-09-23 14 views
19

Có một số constructors cho std::string. Tôi đã tìm kiếm một cách để tránh tái phân bổ và tôi ngạc nhiên rằng có một nhà xây dựng điền nhưng không có "dự trữ" constructor.Tại sao không có hàm tạo đặt trước cho std :: string?

std::string (size_t n, char c); 

nhưng không

std::string (size_t n); 

Vì vậy, tôi phải gọi reserve() sau khi nó đã được phân bổ mặc định (16 byte trong trường hợp của tôi), chỉ để ngay lập tức phân bổ lại nó?

Có lý do tại sao không có nhà xây dựng như vậy để dự trữ không gian trực tiếp khi đối tượng được tạo ra, thay vì phải làm điều đó theo cách thủ công? Hoặc tôi đang thiếu một cái gì đó và có một số cách để làm điều này?

Sử dụng hàm tạo lấp đầy là lãng phí thời gian, vì nó sẽ lặp qua bộ nhớ chỉ để bị ghi đè và cũng gây ra kích thước sai, vì s.length() báo cáo N thay vì 0.

+0

Bạn có chắc chắn 16 byte được đặt trước theo mặc định không? ('sizeof (std :: string)' không có gì để làm với điều đó) – deviantfan

+3

@deviantfan, đó là thực hiện xác định – SingerOfTheFall

+0

@SingerOfTheFall Có, giống như 16 byte quá. Tôi đặc biệt có nghĩa là thực hiện Devolus – deviantfan

Trả lời

3

Đây là tất cả phỏng đoán, nhưng tôi sẽ thử.

Nếu bạn đã biết kích thước của chuỗi mà bạn cần, bạn rất có thể sẽ sao chép dữ liệu từ một nơi khác, ví dụ: từ một chuỗi khác. Trong trường hợp đó, bạn có thể gọi một trong các nhà thầu chấp nhận char * hoặc const std::string & để sao chép dữ liệu ngay lập tức.

Ngoài ra, tôi không thể thấy lý do sử dụng reserve ngay sau khi tạo chuỗi là điều xấu. Trong khi đó là thực hiện xác định, tôi sẽ giả định rằng nó sẽ có ý nghĩa đối với mã này:

std::string str; 
str.reserve(100); 

phân bổ bộ nhớ cho tổng cộng 100 yếu tố, chứ không phải 116 (như trong "phân bổ 16 đầu tiên, sau đó giải phóng họ và phân bổ thêm 100 "), do đó không có tác động hiệu suất đối với hàm tạo không dự trữ.

Ngoài ra, nếu bạn chỉ muốn một trống chuỗi mà không có sự phân bổ mặc định ở tất cả, bạn có thể sử dụng có lẽ std::string str(0, ' '); mà làm mất hiệu lực "Sử dụng constructor điền là một sự lãng phí thời gian" điểm.

+0

Đó là 'std :: string str (0, '');' thực sự ngăn chặn việc phân bổ mặc định (VS2010). Tôi đã nói rằng điều này chỉ xảy ra trong một bản dựng gỡ lỗi, vì vậy nó sẽ không còn là vấn đề nữa, nhưng dù sao, đây là những gì tôi đang tìm kiếm. – Devolus

+0

Khi 'std :: string' cung cấp cho bạn một số dung lượng ban đầu từ hàm dựng mặc định, đó là vì chúng chỉ được tích hợp sẵn với một số không gian ngăn xếp. Không có gì đặc biệt để phân bổ và deallocate. –

0

về cơ bản bạn có thể hỏi cùng một câu hỏi về mọi phương thức std::string không được thể hiện dưới dạng hàm tạo. Ví dụ:

chẳng hạn, tại sao chúng ta không có một hàm tạo có nhiều chuỗi và nối từng chuỗi một với chuỗi mới tạo?

có thể có nhiều lý do tại sao không quá tải một nhà xây dựng dự trữ bộ nhớ. Tôi nghĩ rằng trong một setmind hướng đối tượng, suy nghĩ của một "chuỗi bộ nhớ dành riêng" là một chút kỳ lạ. chuỗi đại diện cho một chuỗi ký tự, không phải bộ nhớ đằng sau nó - đó là chi tiết triển khai, không phải là tính năng chính.
khi ai đó mở một nhà hàng mới, anh ấy nghĩ với chính mình "khi nhà hàng này cuối cùng cũng mở cửa, vào đúng thời điểm mở cửa, tôi sẽ dành 100 chỗ ngồi cho nhóm 100 người bị cáo buộc có thể có hoặc không đến!"

nhưng câu hỏi của bạn ngầm nói rõ điều gì đó rất bỏ: thiếu các đối tượng đệm thích hợp trong C++. bạn hỏi về constructor dự trữ vì bạn muốn sử dụng chuỗi như bộ đệm, nhưng không khởi tạo chúng là rất tốn kém.dự trữ bộ nhớ sẽ không cho phép bạn viết vượt quá kích thước chuỗi.
do đó giải pháp cho vấn đề này là sử dụng unique_ptr<char[]> sẽ không khởi tạo các ký tự, nhưng sẽ cung cấp cho bạn kiểu RAII mà bạn đang tìm kiếm.

+0

Tôi không thấy làm thế nào một đối tượng unique_ptr sẽ giúp đỡ ở đây bởi vì nó không cho tôi các chức năng của std :: string. – Devolus

+0

chức năng nào chẳng hạn? –

+0

Ví dụ: str + = txt; – Devolus

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