2010-08-06 40 views
10

Tôi có một lớp học như thế này:Tại sao hàm dựng C++ quá tải của tôi không được gọi?

class Test{ 
public: 
    Test(string value); 
    Test(bool value); 

}; 

Nếu tôi tạo một đối tượng như thế này:

Test test("Just a test..."); 

Các constructor bool được gọi!

Bất cứ ai cũng biết tại sao?

Cảm ơn

+0

C++ không có phương pháp, btw, chỉ hàm thành viên. Hơn nữa, bạn đang nói về các nhà thầu ở đây. –

+0

Chà, tôi đã gặp phải vấn đề tương tự ngay hôm nay! – Milan

Trả lời

18

Loại "Just a test..."const char *, có thể được ngầm chuyển đổi sang một trong hai bool hoặc std::string. Vì std::string không phải là loại được tích hợp sẵn, const char * s được chuyển đổi thành bool. Bạn có thể ngăn chặn điều đó bằng cách chuyển đổi một cách rõ ràng const char * đến một std::string:

Test test(std::string("Just a test...")); 
+2

Việc sửa chữa là đúng, nhưng giải thích là không hoàn toàn chính xác. Bạn * có thể * chuyển đổi hoàn toàn từ 'const char *' thành 'std :: string' (thông qua một trong các hàm tạo của' std :: string'). Nó chỉ là chuyển đổi bool được ưa thích. –

+0

Tôi sẽ thực hiện thay đổi đó - cảm ơn! –

+1

"Chỉ là một thử nghiệm ..." không phải là char *. Trong C++ nó là char const []. –

4

Loại "Just a test..."const char*. Có một chuyển đổi tích hợp từ con trỏ đến bool được ưu tiên hơn so với chuyển đổi không được tích hợp sẵn từ const char* thành std::string.

Lý do chuyển đổi bool được ưu tiên là vì std::string, trong khi một phần của thư viện chuẩn, không phải là kiểu tích hợp như số nguyên, con trỏ và boolean. Nó hoạt động giống như bất kỳ lớp nào khác và do đó các nhà xây dựng chuyển đổi của nó chỉ được xem xét sau khi chuyển đổi thành các loại được tích hợp sẵn.

8

Đây là một sự khó chịu C++ nổi tiếng.

Chuỗi chữ của bạn có loại trò chuyện const []. Bạn đã có hai nhà thầu, trình tự chuyển đổi từ const char [] để thử nghiệm giống như thế này:

1) const char [] -> const char * -> bool

2) const char [] -> char const * -> std :: string

1) là một chuyển đổi chuẩn được tích hợp trong khi 2) là chuyển đổi do người dùng xác định. Chuyển đổi được tích hợp sẵn được ưu tiên hơn chuyển đổi do người dùng xác định, do đó chuỗi ký tự của bạn được chuyển đổi dễ dàng hơn thành bool so với std :: string.

0

Một cách là tạo ra một biến kiểu std :: string và vượt qua các biến trong:

std::string test = "TEST"; 
A a(test); 

Bằng cách này, loại được một cách rõ ràng định nghĩa là std::string nó sẽ không mặc định cho các nhà xây dựng chấp nhận bool

3

Một cách để vượt qua vấn đề này, là cung cấp một hàm tạo khác lấy một ký tự const * và sau đó chuyển đổi một cách rõ ràng thành chuỗi std ::.

1

Khi bạn có một hàm tạo (đặc biệt là nhiều hàm tạo) chỉ nhận một đối số duy nhất, nó có thể phù hợp để khai báo chúng "rõ ràng" để tránh những kiểu bất ngờ này. Điều này buộc người dùng của lớp phải đảm bảo rằng anh ta cung cấp đúng loại cho hàm tạo mà anh ta muốn sử dụng và ngăn các chuyển đổi loại tiềm ẩn này được thực hiện phía sau người dùng và ẩn khó tìm lỗi.

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=15&rll=1

Trong C++ 0x, điều này đã được mở rộng đến các nhà khai thác chuyển đổi để ngăn chặn vấn đề tương tự

http://www2.research.att.com/~bs/C++0xFAQ.html#explicit-convertion

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