Why is my overloaded C++ constructor not called?
I have a class like this one:
class Test{
public:
Test(string value);
Test(bool value);
};
If I create an object like this:
Test test("Just a test...");
The bool constructor is called!
Anyone knows wh开发者_JS百科y?
Thanks
The type of "Just a test..."
is const char *
, which can be implicitly converted to either bool
or std::string
. Because std::string
isn't a built in type, the const char *
s is converted to a bool
. You can prevent that by explicitly converting the const char *
to a std::string
:
Test test(std::string("Just a test..."));
This is a well known C++ annoyance.
Your string literal has type of chat const[]. You've got two constructors, conversion sequences from char const[] to Test look like this:
1) char const[] -> char const* -> bool
2) char const[] -> char const* -> std::string
1) is a built-in standard conversion whereas 2) is a user-defined conversion. Built-in conversions have precedence over user defined conversions, thus your string literal gets converted more easily to bool than to std::string.
The type of "Just a test..."
is const char*
. There is a built-in conversion from pointers to bool
which is preferred over the non-built-in conversion from const char*
to std::string
.
The reason that the bool conversion is preferred is because std::string
, while part of the standard library, is not a built-in type like integers, pointers, and booleans. It acts like any other class, and so its conversion constructors are considered only after conversions to built-in types.
One way to circumvent this problem, is to provide another constructor taking a const char* and then converting explicitly to a std::string.
When you have a constructor (especially multiple constructors) that take only a single argument, it may be suitable to declare them "explicit" to avoid these kind of surprises. This forces the user of the class to make sure he gives the correct type to the constructor he wishes to use and prevents these implicit type conversions from being done behind the users back and hiding hard to find bugs.
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=15&rll=1
In C++0x, this has been extended to conversion operators to prevent the same issue
http://www2.research.att.com/~bs/C++0xFAQ.html#explicit-convertion
One way is to create a variable of type std::string and pass the variable in:
std::string test = "TEST";
A a(test);
This way the type is explicitly defined as std::string
it won't default to the constructor that accepts bool
精彩评论