2011-10-20 35 views
7

Tôi hiện đang chuyển một ứng dụng C++ sang môi trường bị hạn chế một chút. Ứng dụng sử dụng các lớp STL, chuỗi và luồng. Tôi đang viết lại các phiên bản đơn giản của những thứ này sẽ phát độc đáo trong môi trường của tôi.C++ Fail mà không có định nghĩa toán tử

Điều tôi quan tâm là ứng dụng của tôi đang biên dịch ngay cả khi không có tất cả các định nghĩa toán tử cần thiết. Ví dụ: đối với các lớp chuỗi của tôi, tôi đã xác định:

string operator+ (const string& lhs, const string& rhs); 

và điều này là đủ. Tuy nhiên, tôi nhận thấy có những trường hợp thường có bí ẩn + "một số chuỗi liên tục" và điều này không được định nghĩa trong mã của tôi ở bất kỳ đâu. Khi tôi thêm nó một cách rõ ràng, nó đã được sử dụng:

string operator+ (const string& lhs, const char* rhs); 

Điều gì đang xảy ra trước đó? Nó được biên dịch thành công trước khi tôi thêm hàm thứ hai. Chắc chắn trình biên dịch sẽ không thể suy ra cách nối các chuỗi kiểu c vào lớp chuỗi của tôi.

Tôi đang nhận được hành vi lạ trong chương trình của mình ngay bây giờ và tôi tự hỏi liệu đó có phải do các toán tử khác không được xác định không. Có cách nào để thực thi trình biên dịch để yêu cầu các định nghĩa toán tử như vậy nếu nó cần thiết cho chương trình?

P.S. Lớp chuỗi của tôi nằm trong một không gian tên duy nhất và không liên quan đến tiêu chuẩn ::

+2

Bạn có chuyển đổi hoặc hàm tạo ngầm ẩn đổi từ 'const char *' sang lớp 'string' của bạn không? –

+0

Có, lớp chuỗi của tôi có một hàm tạo với tham số "const char * cstr". Bạn có nghĩ rằng đó có thể là nó? – hayesti

+0

@Bob: [Câu hỏi này] (http://stackoverflow.com/questions/2346083/) có thể được bạn quan tâm. –

Trả lời

12

Không thể chắc chắn nếu không nhìn thấy phần còn lại của mã của bạn, nhưng trong trường hợp này có lẽ cũng không quá khó đoán. Bạn gần như chắc chắn có một hàm tạo cho số string của bạn lấy tham số char const *, vì vậy, trình biên dịch đang sử dụng ctor đó để chuyển đổi char const * thành string, sau đó sử dụng string operator+ (const string& lhs, const string& rhs); để nối nó.

Cho phép điều này xảy ra là một trong (nếu không phải là ) lý do chính cho quá tải các toán tử này bằng hình cầu thay vì hàm thành viên. Là các hàm thành viên, chúng có thể chuyển đổi toán hạng sang phải, nhưng không thể chuyển đổi sang trái.

2

Khi bạn chuyển một số const char*, một đối tượng chuỗi có thể được tạo và chuyển đến toán tử +. Nếu bạn bước qua mã trong trình gỡ lỗi, bạn có thể xác minh hàm khởi tạo đang được gọi.

2

Bạn có thể, có một hàm tạo trong lớp của bạn phải mất const char * làm tham số đầu vào, Rất có thể hàm tạo này được sử dụng cho các lớp phủ ẩn và hành vi lạ bạn thấy.

Tuyên bố công cụ xây dựng của bạn phải mất const char * làm explicit, điều này sẽ vô hiệu hóa việc sử dụng nó cho chuyển đổi tiềm ẩn nơi bạn không định sử dụng nó.

2

Lớp 'chuỗi' của bạn có một hàm tạo đối số có ký tự const * không? Đó có phải là hàm tạo đối số đơn được đánh dấu là 'tường minh' không?

Nếu không rõ ràng, câu trả lời có khả năng nhất là trình biên dịch đang tạo đối tượng chuỗi tạm thời từ char * qua hàm tạo chuyển đổi của bạn và sau đó sử dụng chuỗi tạm thời đó để gọi hai toán tử cộng đối số của bạn.

1

Trình biên dịch không thể biết cách chuyển đổi chuỗi của bạn thành std::string hoặc char* trừ khi bạn chỉ định cách thực hiện.

Tìm các nhà xây dựng chuyển đổi hoặc các toán tử truyền trong khai báo lớp học của bạn.

class MyString 
{ 
    MyString(char*); 
    MyString(std::string); 

    operator std::string(); 
    operator char*(); 
}; 

Đây sẽ được gọi là ngầm.

Bạn có thể chỉ định từ khóa explicit cho hàm tạo của mình để ngăn điều này xảy ra.

Nếu điều này không giải quyết được sự cố, bạn phải có các toán tử bị quá tải ở đâu đó, tốt nhất là tìm chúng qua mã bằng trình gỡ lỗi.