2013-07-30 31 views
7

Một số lớp tôi gặp, có một chuỗi constructor kép:hiệu quả chuỗi constructor

construct(const std::string& s); 
construct(const char* s); 

Có một constructor std::string có lợi ích rõ ràng của việc có thể để vượt qua một std::string mà không c_str(). Tuy nhiên, nếu đối số được lưu trữ trong chuỗi std :: anyway, có lợi ích gì khi có hàm tạo const char* không?

Đặc biệt:

construct(const std::string& s) : m_string(s) {} 
construct(const char* s) : m_string(s) {} 
std::string m_string; 

các nhà xây dựng thứ hai Sẽ nhanh hơn cho xâu và char* biến, hoặc nó sẽ được tối ưu hóa đi?

Câu hỏi bổ sung - không C++ 11 di chuyển xây dựng có thay đổi gì ở đây không?

+0

Trong C++ 11 với cấu trúc di chuyển, bạn có thể sử dụng (như một ctor đơn cho cả hai): 'construct (std :: string s): m_string (std :: move (s)) {}'. Không hiệu quả như chuyển tiếp hoàn hảo, nhưng gần như (hai di chuyển tạm thời). – dyp

+0

'std :: string (" Hello There ")' đó là lý do tại sao bạn có một hàm tạo cho 'const char *', nhưng tôi không chắc bạn đang hỏi gì ở đây ... – user2485710

+0

nó không phải nhanh hơn, nó chỉ là một constructor thứ hai bị quá tải để xử lý đơn giản hơn – Alex

Trả lời

8

trong C++ 03, hoặc trong C++ 11 wit hout xác định ngữ nghĩa di chuyển, việc chuyển đổi ẩn const char * sang std::string ẩn sẽ tạo chuỗi tạm thời, sau đó được sao chép vào thành viên. Điều này thực hiện một bản sao thêm.

Trong C++ 11 bạn có thể có tạm thời di chuyển thay vì sau khi đi ngang qua giá trị:

construct(std::string s) : member(std::move(s)) {} 

Chỉ khác điều tôi có thể nghĩ đến là khả năng tương thích với các lớp khác cung cấp các nhà khai thác chuyển đổi.

struct String { 
    operator char const *() const; 
}; 

Vì chỉ có một chuyển đổi người dùng định nghĩa có thể áp dụng ngầm, các std::string chức năng sẽ không nhận được một cuộc tranh luận String bởi chuyển đổi qua char const *. Tuy nhiên, lưu ý rằng với hàm chuyển đổi bổ sung là std::string và cả hai hàm tạo, kết quả sẽ là quá tải không rõ ràng.

+0

Vấn đề khác là (như tôi nhận thấy) rằng nó sẽ không trải qua xây dựng ngầm từ một chữ. .. là việc thực hiện với std :: move() hiệu suất tốt hơn khôn ngoan? –

+0

@KornelKisielewicz Tôi không hiểu. Không có gì ở đây là bảo vệ chống lại các chữ, bạn có thể minh họa vấn đề này không? Và bạn không cần phải gọi 'std :: move' để chuyển ngữ nghĩa từ tạm thời. Nếu có bất kỳ sự khác biệt nào, việc di chuyển từ tạm thời có thể chậm hơn so với việc xây dựng từ một con trỏ trực tiếp. – Potatoswatter

+0

@Potatoswatter Vấn đề là nếu bạn sử dụng 'xây dựng (std :: chuỗi const & p): m_string (p)' bạn sẽ sao chép tạm thời. – dyp

5

Nếu bạn chỉ có char* và chỉ có hàm tạo đầu tiên, bản sao có thể được thực hiện 2 lần. in std::string(char*) và trong construct(std::string)

Trong khi con trỏ hàm khởi tạo thứ hai sẽ được sao chép (nhanh) và sau đó sao chép chuỗi.

Trong C++ 11 ý tưởng tốt là tạo ra 1 constructor

construct(std::string s) : m_string(std::move(s)) {} 

Trong trường hợp này nếu bạn có chỉ char* dữ liệu có thể được sao chép trong chuỗi ctor, nhưng chuỗi sẽ chỉ là tạm thời, vì vậy nó sẽ chỉ di chuyển trong construct ctor

This code in "tạo ra, sao chép"
This code in "tạo, di chuyển"

+0

Tại sao nó sẽ sao chép 2 lần? – billz

+0

@billz, Trong chuỗi (char *) ctor và sau đó trong xây dựng (string) – RiaD

+0

@DyP, sao chép & dán là ác :) cố định – RiaD

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