Почему мой перегруженный конструктор C ++ не вызывается? - PullRequest
10 голосов
/ 06 августа 2010

У меня есть такой класс:

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

};

Если я создаю такой объект:

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

Конструктор bool называется!

Кто-нибудь знает почему?

Спасибо

Ответы [ 6 ]

18 голосов
/ 06 августа 2010

Тип "Just a test..." равен const char *, который может быть неявно преобразован в bool или std::string. Поскольку std::string не является встроенным типом, const char * s преобразуется в bool. Вы можете предотвратить это, явно преобразовав const char * в std::string:

Test test(std::string("Just a test..."));
8 голосов
/ 06 августа 2010

Это хорошо известное раздражение в C ++.

Ваш строковый литерал имеет тип chat const [].У вас есть два конструктора, последовательности преобразования из char const [] в Test выглядят так:

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

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

1) - это встроенное стандартное преобразование, тогда как 2) - преобразование, определяемое пользователем.Встроенные преобразования имеют приоритет над пользовательскими преобразованиями, поэтому ваш строковый литерал конвертируется в bool легче, чем в std :: string.

4 голосов
/ 06 августа 2010

Тип "Just a test..." равен const char*.Существует встроенное преобразование из указателей в bool, которое предпочтительнее, чем не встроенное преобразование из const char* в std::string.

Причина, по которой преобразование bool является предпочтительным, заключается в том, что1008 *, хотя и является частью стандартной библиотеки, не является встроенным типом, таким как целые числа, указатели и логические значения.Он действует как любой другой класс, и поэтому его конструкторы преобразования рассматриваются только после преобразования во встроенные типы.

3 голосов
/ 06 августа 2010

Одним из способов обойти эту проблему является предоставление другого конструктора, принимающего const char * и затем явно преобразующего в std :: string.

1 голос
/ 06 августа 2010

Если у вас есть конструктор (особенно несколько конструкторов), который принимает только один аргумент, может быть целесообразно объявить их «явными», чтобы избежать подобных неожиданностей. Это вынуждает пользователя класса удостовериться, что он предоставляет правильный тип конструктору, который он хочет использовать, и предотвращает выполнение этих неявных преобразований типов за спиной пользователя и скрывает трудно найти ошибки.

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

В C ++ 0x это было расширено для операторов преобразования, чтобы предотвратить ту же проблему

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

0 голосов
/ 06 августа 2010

Один из способов - создать переменную типа std :: string и передать переменную в:

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

Таким образом, тип явно определяется как std::string, он не будет по умолчанию для конструктора, который принимает bool

...