Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.138.69.45] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Часто в исходниках видел перед методами служебное слово explicit, скажите, пожалуйста, зачем оно нужно и что оно делает?
|
Сообщ.
#2
,
|
|
|
Запрещает неявное преобразование
Используется в конструкторах с одним параметром. |
Сообщ.
#3
,
|
|
|
Цитата Крон @ Используется в конструкторах с одним парамтером. При чём тут один параметр? Используется для того, чтобы конструктор задавали явно. |
Сообщ.
#4
,
|
|
|
А как можно неявно задать конструктор с более чем один параметром?
|
Сообщ.
#5
,
|
|
|
Цитата Крон @ А как можно неявно задать конструктор с более чем один параметром? class A { A(int first, int second); ~A(); }; |
Сообщ.
#6
,
|
|
|
Цитата Алкаш @ Используется для того, чтобы конструктор задавали явно. Ок, а что такое по твоему "задать конструктор"? DelphiLexx, struct A { A(int) { } }; struct B { explicit B(int) { } }; int main() { A a1(5); // ok B b1(5); // ok A a2 = 10; // ok B b2 = 10; // error <<<========================== } |
Сообщ.
#7
,
|
|
|
Цитата archimed7592 @ Ок, а что такое по твоему "задать конструктор"? Цитата archimed7592 @ B b1(5); // ok |
Сообщ.
#8
,
|
|
|
Цитата Алкаш @ Цитата Крон @ Используется в конструкторах с одним парамтером. При чём тут один параметр? Используется для того, чтобы конструктор задавали явно. Интересно а для чего использовать тогда explicit c конструктором который имеет более чем один параметр? Я просто не вижу смысла потому что приведение и так неявное невозможно. А archimed7592 уже ответил на вопрос полностъю я считаю. |
Сообщ.
#9
,
|
|
|
Цитата Craft @ Интересно а для чего использовать тогда explicit c конструктором который имеет более чем один параметр? struct S { /*explicit*/ S(int, int = 0) {} }; int main() { S s = 10; } раскомментируй explicit |
Сообщ.
#10
,
|
|
|
class Foo { public: Foo(const std::string & sString, bool Flag = true); Foo(bool Flag); ... }; Вот пример такой класс, а теперь прикол : Foo("foo"); Вызывется 2-ой конструктор, а не первый. Понятно что есть небольшая ошибка, что ведь нужен обьект типа string, а я передаю const char * - это простая ошибка которая может возникнуть в процессе кодирования, когда нету autocomplete и программист уже устал. Если сделать оба конструктора explicit, такой ошибки не будет и компилятор предупредит об этой ошибки с неявным преобразованием. На эту ошибку наткнулся в реальном коммерческом проекте. Вывод : всегда делать конструкторы explicit, если у него есть параметры. |
Сообщ.
#11
,
|
|
|
Alek86 Я не имел ввиду что конструктор принимает значения по умолчанию. Так можна и 10 аргументов инициализировать по умолчанию. Ты же инициализуеш неявно только первый аргумент, а остальныи присваиваеш значение по умолчанию. Я знаю как работает explicit и для чего он нужен.
Допустим без explicit у тебя конструктор автоматически определил бы преобразования из int в твой клас S, ну создаст он стек на 10 елементов. Да не спорю это не то что мы ожидаем. Но первая переменная у тебя всё равно получит значение 10. Так работает неявное преобразование. Большой минус только что стек сильно увеличивается. Это неправильный стиль я не спорю. Но чтоб считать это такой уж ошибкой я не вижу смысла. Программист должен знать что он делает в первую очередь. Пусть хоть на миллион элементов неявно инициализацию использует. Лиш бы ему памъяти хватило чтоб небыло переполнения. Просто насколько мне не изменяет памъять то у windows под кучю выделяется 1Мб так что если не жалко израсходованой памъяти то можна такой метод использовать. Я никогда не видел что ктото использовал неявное преобразование на подобие этого S s = 10; P.S. Если чесно, то я не подумал, когда писал ответ, про возможность передачи значения по умолчанию. Cechmanek Foo("foo"); Разве что через такую Foo p = "foo"; Цитата B b1(5); // ok |
Сообщ.
#12
,
|
|
|
Цитата Cechmanek @ Вызывется 2-ой конструктор, а не первый. Это потому что последовательность преобразований из массива char в bool - стандартная, а в std::string - пользовательская. При разрешении перегрузки предпочтение отдаётся последовательности стандартных преобразований. Цитата Cechmanek @ Если сделать оба конструктора explicit то в этом плане ничего не изменится. Цитата Cechmanek @ Вывод : всегда делать конструкторы explicit, если у него есть параметры. Плохой вывод. |
Сообщ.
#13
,
|
|
|
Один из способов из способов избежать создания временных объектов это по возможности использовать объявления конструкторов как
explicit Вот и все. |
Сообщ.
#14
,
|
|
|
Цитата Craft @ Начинающий программист в основном не использует explicit, а опытный программист просто напросто никогда не напишет такой код который я написал више. ты считаешь, что опытный программист - это безошибочная машина для написания кода? огорчяу тебя - даже "сеньоры" с огромным стажем работы ошибаются и достаточно нередко - специфика работы такая, что всего умом не охватишь (у макконелла написано как от этого максимально откреститься (путем упрощения кода) но на практике так круто никто не пишет ) потому и придуманы специальные "ограничители", чтобы ошибьки не так плодились. типа приватных членов класса, приватного наследования, explicit, попытались добавить спецификацию throw функции и т.п. и потому же рекомендуют пореже писать кастомных операторов преобразования насчет правила "ставить explicit всегда и везде" не согласен, но только потому что не обжигался на этом "в реале" я ставлю его только тогда, когда "чувствую" что тут его лучше поставить |
Сообщ.
#15
,
|
|
|
Craft и Archimed раскрыли тему полностью
Цитата Один из способов из способов избежать создания временных объектов это по возможности использовать объявления конструкторов как временные объекты здесь вообще не при чём. |