2009-10-28 31 views
9

Tôi đang gặp một số phương pháp quá tải sự cố trong C++. Ví dụ về vấn đề này, tôi có một lớp với một số phương thức đang bị quá tải, và mỗi phương thức có một tham số với một kiểu dữ liệu khác. Câu hỏi của tôi: là có một thứ tự cụ thể trong lớp những phương pháp này sẽ xuất hiện trong, để đảm bảo phương pháp chính xác được gọi là tùy thuộc vào kiểu dữ liệu tham số của nó?Chức năng/Phương pháp Quá tải C++: Sự nhầm lẫn kiểu dữ liệu?

class SomeClass{ 
    public: 
    ... 
    void Method(bool paramater); 
    void Method(std::string paramater); 
    void Method(uint64_t paramater); 
    void Method(int64_t paramater); 
    void Method(uint8_t paramater); 
    void Method(int8_t paramater); 
    void Method(float paramater); 
    void Method(double paramater); 
    void Method(ClassXYZ paramater); 
} 

tôi nhận thấy có vấn đề vì khi chạy:

Method("string"); 

nó được gọi:

Method(bool paramater); 

Trả lời

5

Chuỗi đen "string" có kiểu const char[] mà có thể được chuyển đổi sang implicity bool. Đây là ứng cử viên chuyển đổi tốt nhất cho một trong các chức năng quá tải của bạn mặc dù nó không có khả năng là một trong những hữu ích nhất.

Nếu ý định của bạn là xử lý chuỗi ký tự bằng cách quá tải lấy std::string, thì bạn cần thêm quá tải chụp const char* và thực hiện cuộc gọi phiên bản std::string.

+0

NÀY LÀ HOÀN TẤT HOÀN THÀNH. Quy tắc giải quyết này không đạt được một khái niệm cơ bản như vậy. Có lẽ OP "theo thứ tự tuyên bố" cách tiếp cận trực quan sẽ làm một công việc tốt hơn. –

4

Đơn đặt hàng không quan trọng. Vấn đề ở đây là khi bạn gọi

Method("string"); 

bạn đang chuyển một cụm từ const []. Điều này sẽ được chuyển đổi thành bool ngầm. Những gì bạn muốn làm là vượt qua một std :: string rõ ràng:

Method(std::string("string")); 
+0

Không cast; xây dựng! std :: string ("chuỗi") (hoặc thực hiện một tình trạng quá tải để char * như đã nói ở trên) –

+0

Dĩ nhiên; đã chỉnh sửa, cảm ơn. – Tomas

23

Thứ tự không có sự khác biệt. Phương thức gọi được chọn bằng cách phân tích các kiểu đối số và kết hợp chúng với các kiểu tham số. Trong trường hợp không có kết hợp chính xác, phương thức phù hợp nhất sẽ được chọn. Trong trường hợp của bạn, nó sẽ là phương thức bool.

Bạn đang cung cấp đối số thuộc loại const char[7]. Theo quy tắc quá tải C++, đường dẫn tốt nhất ở đây là để const char[7] phân rã thành const char * và sau đó chuyển đổi nó thành bool bằng cách sử dụng chuyển đổi chuẩn. Đường dẫn có chuyển đổi thành std::string được coi là tồi tệ hơn vì đường dẫn sẽ liên quan đến chuyển đổi do người dùng xác định từ const char * đến std::string. Nói chung, chuyển đổi do người dùng xác định mất quá trình giải quyết quá tải cho chuyển đổi chuẩn. Đây là những gì xảy ra trong trường hợp của bạn.

Nếu bạn cần phiên bản std::string được gọi ở đây, cung cấp một quá tải rõ ràng cho const char * loại, và ủy thác cuộc gọi đến phiên bản std::string bằng cách chuyển đổi các tham số để std::string loại một cách rõ ràng

void Method(const char *paramater /* sic! */) 
{ 
    Method(std::string(paramater)); 
} 
+1

chưa được xác định -> do người dùng xác định? – jalf

+0

Đã sửa lỗi. Cảm ơn bạn. – AnT

1

Như Charles đã chỉ ra, điều này xảy ra do chuyển đổi tiềm ẩn không mong muốn. Nếu bạn muốn tránh điều đó, sử dụng một constructor std :: string: Method(std::string("string")); hoặc bỏ nó vào std :: string:

Method(static_cast<std::string>("string")); 

Tuy nhiên, thứ tự của tờ khai của bạn là không quan trọng.Ngoài ra, hãy kiểm tra chính tả của từ "tham số";)

1

Ngoài vấn đề chuỗi, còn có một số khác. int64_t và int8_t là (thường) typedefs. Vì typedef chỉ là bí danh, chúng có thể tham chiếu đến cùng loại trong trường hợp quá tải trường hợp không hoạt động. Nhưng điều này là khá khó xảy ra trong trường hợp của bạn. Chỉ muốn đề cập đến nó.

2

Không trả lời câu hỏi của bạn nhưng, chỉ vì tò mò, có lý do ẩn nào để không sử dụng phương thức mẫu thay vì xác định phiên bản quá tải cho từng loại không?

class SomeClass 
{ 
    public: 
    ... 
    template <typename T> 
    void Method(T paramater); 
}; 
+0

Điều này là tốt đẹp bởi vì nó sẽ vô hiệu hóa các chuyển đổi tự động bắt đầu trở nên kỳ lạ. Bạn cũng có thể xác định phương thức của mình chỉ cho một vài chuyên ngành mà bạn dự định hỗ trợ. –

1

Bạn có thể thêm một explict từ khóa để lấy đối số dự định.