2009-07-24 40 views
19

Tôi đã gặp phải một tình huống thú vị hôm nay trong một chương trình mà tôi vô tình gán một số nguyên không dấu vào một chuỗi std ::. Trình biên dịch Visual Studio C++ không đưa ra bất kỳ cảnh báo hoặc lỗi nào về nó, nhưng tôi đã tình cờ nhận ra lỗi khi tôi chạy dự án và nó đã cho tôi các ký tự rác cho chuỗi của tôi.Tại sao C++ cho phép một số nguyên được gán cho một chuỗi?

Đây là loại gì mã trông giống như:

std::string my_string(""); 
unsigned int my_number = 1234; 
my_string = my_number; 

Các mã sau đây cũng biên dịch tốt:

std::string my_string(""); 
unsigned int my_number = 1234; 
my_string.operator=(my_number); 

Kết quả sau một lỗi:

unsigned int my_number = 1234; 
std::string my_string(my_number); 

gì đang diễn ra? Làm thế nào đến trình biên dịch sẽ ngừng xây dựng với khối mã cuối cùng, nhưng để cho 2 khối mã đầu tiên xây dựng?

+0

Lỗi trình biên dịch là gì? Đối với tôi, g ++ v4.4 biên dịch và hoạt động chính xác – CsTamas

+0

Tôi xin lỗi, tôi đã phạm sai lầm với khối mã thứ 2 - nó biên dịch. Điều cuối cùng không thành công với một lỗi về việc không có một std :: string constructor chấp nhận một unsigned int. – user55417

Trả lời

28

Vì chuỗi được gán từ charint được chuyển đổi hoàn toàn thành char.

+0

Làm thế nào để int không được đúc hoàn toàn cho 2 khối cuối cùng? Ý bạn là tôi không thể gọi toán tử = rõ ràng? Bởi vì các công trình sau đây: my_string.operator = ("hello world"); – user55417

+0

Không phải là 'my_string.operator = (my_number)' một lệnh gọi rõ ràng tới 'operator ='? Tôi đang hiểu nhầm điều gì ở đây? – sbi

+0

"Làm thế nào đến int không được đúc hoàn toàn cho 2 khối cuối cùng?" Bởi vì trong khi 1234 phù hợp trong 16 bit, và có thể có một char, không phải mọi int unsigned sẽ phù hợp trong 16 bit. Ngay sau khi bạn chỉ định một loại có phạm vi lớn hơn một char, bạn đã ngừng trình biên dịch từ ngầm đúc giá trị vào một char. –

20

Các std :: string lớp có toán tử gán sau đây định nghĩa:

string& operator=(char ch); 

Toán tử này được gọi bởi chuyển đổi ngầm của unsigned int để char.

Trong trường hợp thứ ba, bạn đang sử dụng một constructor rõ ràng để nhanh chóng một std::string, không ai trong số các nhà thầu có sẵn có thể chấp nhận một unsigned int, hoặc sử dụng chuyển đổi ngầm từ unsigned int:

string(); 
string(const string& s); 
string(size_type length, const char& ch); 
string(const char* str); 
string(const char* str, size_type length); 
string(const string& str, size_type index, size_type length); 
string(input_iterator start, input_iterator end); 
+3

"toán tử không thể được gọi bằng cú pháp gọi hàm". 13.5 (4) trong tiêu chuẩn C++ nói rằng chúng có thể. Các toán tử " –

+0

" không thể được gọi bằng cú pháp gọi hàm "Đó là sai. – sbi

+1

Xấu hổ, bởi vì câu trả lời được chấp nhận thực hiện cùng một sai lầm lúc đầu nhưng đã được bình chọn lên và sau đó sửa chữa, trong khi câu trả lời này là tốt hơn nhiều và đã bỏ phiếu xuống. Tôi sẽ bỏ phiếu cho điều này nếu nó cố định. –

2

Nó chắc chắn là operator = (char ch) gọi - trình gỡ lỗi của tôi đã bước vào đó. Và MS VS 2005 của tôi biên dịch sau mà không có lỗi.

std::string my_string(""); 
unsigned int my_number = 1234; 
my_string = my_number; 
my_string.operator=(my_number); 
0

tôi có thể giải thích các tình huống đầu tiên và thứ ba:

my_string = 1234; 

này hoạt động vì chuỗi đã ghi đè operator = (char). Bạn đang thực sự gán một ký tự (với tràn dữ liệu) vào chuỗi. Tôi không biết tại sao trường hợp thứ hai dẫn đến lỗi biên dịch. Tôi đã thử mã với GCC và nó biên dịch.

std::string my_string(1234); 

sẽ không hoạt động, vì không có hàm tạo chuỗi có tham số char hoặc int.

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