Why is my overloaded C++ constructor not called?

为君一笑 提交于 2019-12-09 15:52:22

问题


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 why?

Thanks


回答1:


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..."));



回答2:


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.




回答3:


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.




回答4:


One way to circumvent this problem, is to provide another constructor taking a const char* and then converting explicitly to a std::string.




回答5:


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




回答6:


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



来源:https://stackoverflow.com/questions/3425015/why-is-my-overloaded-c-constructor-not-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!