tag:blogger.com,1999:blog-5744154463195670470.post6339240710063960706..comments2016-04-03T23:09:08.329+03:00Comments on Code @ C++: explicit constructorKirill V. Lyadvinskyhttp://www.blogger.com/profile/03118738824565485127noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-5744154463195670470.post-52494932077259461042008-07-10T09:59:00.000+04:002008-07-10T09:59:00.000+04:00да в С++ вообще много где можно ошибиться ;-)да в С++ вообще много где можно ошибиться ;-)Yuri Volkovhttps://www.blogger.com/profile/10400110255029957028noreply@blogger.comtag:blogger.com,1999:blog-5744154463195670470.post-4868554179197272702008-07-09T18:13:00.000+04:002008-07-09T18:13:00.000+04:00Все верно, но суть была в том, что легко ошибится ...Все верно, но суть была в том, что легко ошибится и получить неожиданный результат.Kirill V. Lyadvinskyhttps://www.blogger.com/profile/03118738824565485127noreply@blogger.comtag:blogger.com,1999:blog-5744154463195670470.post-60177748430185332252008-07-09T13:32:00.000+04:002008-07-09T13:32:00.000+04:00ANSI ISO/IEC 14882:2003(E)12.3.1 Conversion by con...ANSI ISO/IEC 14882:2003(E)<BR/>12.3.1 Conversion by constructor<BR/><I>A constructor declared without the function-specifier explicit that can be called with a single parameter specifies a conversion from the type of its first parameter to the type of its class. Such a constructor is called a converting constructor. <BR/><BR/>class X {<BR/>// ...<BR/>public:<BR/>X(int);<BR/>X(const char*, int =0);<BR/>};<BR/><BR/>An explicit constructor constructs objects just like non-explicit constructors, <B>but does so only where the direct-initialization syntax (8.5) or where casts (5.2.9, 5.4) are explicitly used.</B> A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization or value initialization<BR/>(8.5).<BR/></I><BR/>и далее по тексту. Это ответ на вопрос "А по какому праву?". По тому какой синтаксис был использован в выражении (sss xxx = 7;) компилятор определяет какой конструктор должен быть вызван. Про неявное преобразование типов рассказывать думаю будет лишним.Yuri Volkovhttps://www.blogger.com/profile/10400110255029957028noreply@blogger.comtag:blogger.com,1999:blog-5744154463195670470.post-35500519512563748292008-07-08T19:55:00.000+04:002008-07-08T19:55:00.000+04:00Yuriy Volkov! Попробуйте еще раз вникнуть в суть с...Yuriy Volkov! Попробуйте еще раз вникнуть в суть статьи. Существует два конструктора. В обоих случаях автор кода хочет вызывать тот, что принимает на вход int. Это следует из того, что в качестве аргумента выступает число 7 (а не 7.0, например). Ожидаемое поведение компилятора - это ошика, так как конструктор для int объявлен как explicit, потому не может быть скомпилирован вариант "sss xxx = 7;". Однако, компилиятор делает нехорошую вещь: он выбрасывает из перегрузки конструктор для int (а по какому праву?) и рассматривает только конструктор с double. Компилятор должен видеть, что конснтруктор для int существует, что автор кода вызывает именно его и ругаться, что такой вызов незаконный, так как он объявлен explicit. Этого ожидает разработчик, вель ровно так и происходит, если вместо explicit вы объявите конструктор закрытым: компилятор не закроет глаза на то, что конструктор теперь private, вызвав public-вариант с double-аргументом, он выругается и поделом! Хотелось бы аналогичного поведения и для explicit, но увы, С++ ведет себя не так.malistovhttps://www.blogger.com/profile/04649550787635910346noreply@blogger.comtag:blogger.com,1999:blog-5744154463195670470.post-47335689733619395262008-07-08T17:56:00.000+04:002008-07-08T17:56:00.000+04:00ну ошибкой считалось бы наверняка если бы отсутств...ну ошибкой считалось бы наверняка если бы отсутствовал второй конструктор. А в приведенном примере даже ворнинга о преобразовании int в double выдаваться не будет, да и не должно. Если бы double->int то некоторые компиляторы выдают предупреждения из серии "loss of data".Yuri Volkovhttps://www.blogger.com/profile/10400110255029957028noreply@blogger.comtag:blogger.com,1999:blog-5744154463195670470.post-89078503837392503522008-07-08T14:20:00.000+04:002008-07-08T14:20:00.000+04:00explicit указывает на требования явной формы конст...explicit указывает на требования явной формы конструктора копий.<BR/><BR/>Я пишу о том, что оно ещё и скрывает конструктор. Т.е. я бы хотел, чтобы компилятор выдавал ошибку о том, что требуется явный вызов, а не вызывал по тихому конструктор копий для double...Kirill V. Lyadvinskyhttps://www.blogger.com/profile/03118738824565485127noreply@blogger.comtag:blogger.com,1999:blog-5744154463195670470.post-10445142624570280422008-07-08T14:02:00.000+04:002008-07-08T14:02:00.000+04:00explicit и было введено, если мне неизменяет памят...explicit и было введено, если мне неизменяет память для того чтобы запретить подобное поведение, если оно нежелательно.Yuri Volkovhttps://www.blogger.com/profile/10400110255029957028noreply@blogger.com