Форум: "Прочее";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
ВнизА я и не знал... Найти похожие ветки
← →
Игорь Шевченко © (2010-03-05 22:47) [120]Kerk © (05.03.10 22:14) [119]
> > И вообще, конструктор не должен делать ничего такого,
> что
> > может вызвать исключение.
> > Для этого есть другие методы, например Init и LoadFromFile.
>
Ну это слишком фанатично. И не слишком умно. Как говорил один неглупый человек, задача должна быть решена минимальным числом максимально понятных строка кода. Делать намеренно два метода, один Create, другой Init, значит противоречить этому утверждению.
← →
Piter © (2010-03-05 22:54) [121]Kerk © (05.03.10 22:14) [119]
Я с этим не согласен
поддерживаю. Я не понимаю зачем нужно:
My := MyClass.Create;
My.Init;
Если можно так:
My := MyClass.Create;
Я могу понять, что кто-то к чему-то привык, это на самом деле важно, привычки позволяют нам не ломать голову на пустом месте. Но если говорить абстрактно, не касаясь опыта того или иного человека, то я не вижу разницы в этих двух подходах. Не позволяет / не приветствует средство разработки вызов исключения в конструкторе - вариант номер 1. Разрешает - вариант номер два.
Да и как уже отметили, код конструктора в дельфовом понимании это скорее похоже на событие, выполнение некоего участка кода с посылом "объект создан, давай инициализируй что тебе нужно". Можно рассматривать это как событие OnCreate. С некоторой магией:
1) вызов конструктора неявно приводит к вызову NewInstance
2) вызов исключения в конструкторе неявно приводит к вызову деструктора
← →
Anatoly Podgoretsky © (2010-03-05 23:09) [122]> vuk (05.03.2010 21:03:48) [108]
Правильно, пусть что то делает деструктор, он же не конструктор.
← →
Kerk © (2010-03-05 23:30) [123]
> Piter © (05.03.10 22:54) [121]
> Но если говорить абстрактно, не касаясь опыта того или иного
> человека, то я не вижу разницы в этих двух подходах.
Разница есть. Разработчик работает с кодом не один, да и он сам не идеален. А ошибиться вMyComp := TMyComp.Create(a,b,c,d);
намного сложнее, чем вMyComp := TMyComp.Create;
MyComp.Init(a);
MyComp.bProp := b;
MyComp.cProp := c;
MyComp.dProp := d;
← →
Eraser © (2010-03-05 23:33) [124]> [121] Piter © (05.03.10 22:54)
> поддерживаю. Я не понимаю зачем нужно:
>
> My := MyClass.Create;
> My.Init;
>
> Если можно так:
>
> My := MyClass.Create;
вот так нельзя, если есть явная опасность исключения, например в TFileStream.Create (один из немногих примеров такого типа, который часто попадается в жизни).
в этом случае нужно городить лишний обработчик исключения.
а убери они открытие/создание файла в Init. Можно было бы использовать стандартный подход.FS := TFileStream.Create();
try
FS.Init(file, mode);
finally
FS.Free;
end;
хорошим тоном было бы сделать и такой тип конструктора, на то и придумана overload.
← →
Kerk © (2010-03-05 23:56) [125]
> Eraser © (05.03.10 23:33) [124]
А сделай они вместо исключения в Init возврат кода ошибки, то можно было бы обойтись вообще без try-finally. На то и придумана overload.
Шутка:)
Но как всегда с долей шутки.
← →
Piter © (2010-03-05 23:59) [126]Kerk © (05.03.10 23:30) [123]
тут я не согласен. Почему присвоение параметров в 4 строки более ошибочно, чем присвоение в одной строчке? Удобнее в одну строку - да (если все параметры обязательно надо задать), но менее ошибочно?
Eraser © (05.03.10 23:33) [124]
в этом случае нужно городить лишний обработчик исключения
почему лишний и почему городить? Сработает просто вышестоящий обработчик исключений.
← →
Kerk © (2010-03-06 00:01) [127]
> Piter © (05.03.10 23:59) [126]
>
> Kerk © (05.03.10 23:30) [123]
>
> Почему присвоение параметров в 4 строки более ошибочно,
> чем присвоение в одной строчке?
Как минимум потому, что без всякой документации сам конструктор говорит тебе какие данные нужны для инициализации класса.
← →
Демо © (2010-03-06 00:04) [128]
> тут я не согласен. Почему присвоение параметров в 4 строки
> более ошибочно, чем присвоение в одной строчке? Удобнее
> в одну строку - да (если все параметры обязательно надо
> задать), но менее ошибочно?
Потому что для объекта может быть необходима инициализация всех четырёх полей.
Разработчик же запросто при таком подходе может оставить непроинициализированным одно из них.
← →
Eraser © (2010-03-06 00:11) [129]> [126] Piter © (05.03.10 23:59)
> Сработает просто вышестоящий обработчик исключений.
а если его нету? т.к. при конструировании других объектов исключений быть не может. тогда для TFileStream нужно городить отдельно. ничего катастрофического в этом нет, но мешает.
насчет параметров в конструкторе - не вижу ничего плохого.
← →
Игорь Шевченко © (2010-03-06 00:16) [130]
> т.к. при конструировании других объектов исключений быть
> не может
Может
← →
Eraser © (2010-03-06 00:37) [131]> [130] Игорь Шевченко © (06.03.10 00:16)
и много таких классов в VCL?
← →
Игорь Шевченко © (2010-03-06 00:38) [132]Eraser © (06.03.10 00:37) [131]
Все
← →
vuk © (2010-03-06 00:43) [133]to Anatoly Podgoretsky © (05.03.10 23:09) [122]
> Правильно, пусть что то делает деструктор, он же не конструктор.
А вдруг и там что-то случится? :) Недоразрушенные экземпляры ничем не лучше, чем недоинициализированные. Даже хуже.
P.S. Не, я предлагаю ваще нигде ничего не делать. Совсем ошибок не будет!
← →
Eraser © (2010-03-06 00:55) [134]> [132] Игорь Шевченко © (06.03.10 00:38)
ну если следовать такой логике, то почти в любой строчке кода можно на AV нарваться или еще что по хуже.
что то я не видел во всех классах внутри конструкторов raise ESomeException.
← →
Игорь Шевченко © (2010-03-06 01:09) [135]Eraser © (06.03.10 00:55) [134]
> ну если следовать такой логике, то почти в любой строчке
> кода можно на AV нарваться или еще что по хуже
http://transl-gunsmoker.blogspot.com/2009/03/blog-post_2362.html
← →
Германн © (2010-03-06 01:29) [136]
> Eraser © (06.03.10 00:37) [131]
>
> > [130] Игорь Шевченко © (06.03.10 00:16)
>
> и много таких классов в VCL?
> Игорь Шевченко © (06.03.10 00:38) [132]
>
> Eraser © (06.03.10 00:37) [131]
>
> Все
>
Один про Фому, другой про Ерёму, имхо.
← →
Германн © (2010-03-06 01:34) [137]
> Игорь Шевченко © (06.03.10 01:09) [135]
>
> Eraser © (06.03.10 00:55) [134]
>
>
> > ну если следовать такой логике, то почти в любой строчке
> > кода можно на AV нарваться или еще что по хуже
>
>
> http://transl-gunsmoker.blogspot.com/2009/03/blog-post_2362.
> html
>
Если бы я или кто другой привел примеры из этой статьи в доказательство своих утверждений о чем-то, ты Игорь был бы первым, кто сказал бы, что виноват я. Ибо не следует так писать компоненты.
← →
Eraser © (2010-03-06 02:10) [138]> [135] Игорь Шевченко © (06.03.10 01:09)
не ясна мораль данного примера, в контексте дискуссии данной ветки.
← →
Германн © (2010-03-06 02:23) [139]
> Eraser © (06.03.10 02:10) [138]
>
> > [135] Игорь Шевченко © (06.03.10 01:09)
>
> не ясна мораль данного примера, в контексте дискуссии данной
> ветки.
>
Один про Фому, другой про Ерёму, имхо. :)
т.е. Один про генофонд, другой х.з. о чем :)
← →
Игорь Шевченко © (2010-03-06 02:26) [140]Eraser © (06.03.10 02:10) [138]
Мораль данного примера состоит в том, что код с исключениями надо писать с учетом того, что исключение может возникнуть практически в любой строке кода. В частности, даже при банальном вызове TObject.Create может возникнуть исключение EOutOfMemory
← →
Аноним © (2010-03-06 02:30) [141]
> В частности, даже при банальном вызове TObject.Create может
> возникнуть исключение EOutOfMemory
что делать в такой ситуации? :-)
← →
Eraser © (2010-03-06 02:35) [142]> [140] Игорь Шевченко © (06.03.10 02:26)
безусловно может возникнуть. но это уже форсмажор. если в программе где-то портится память, то там уже никакая обработка исключений не спасет. для таких вещей, по-моему, больше подходит централизованная обработка исключений, вроде багрепортов, эврики и т.п.
в случае же TFileStream.Create исключение - это вполне штатное поведение.
← →
Аноним © (2010-03-06 02:38) [143]
> для таких вещей, по-моему, больше подходит централизованная
> обработка исключений
лисп, схема, хаскелл :-)
← →
Германн © (2010-03-06 02:41) [144]
> Игорь Шевченко © (06.03.10 02:26) [140]
>
> Eraser © (06.03.10 02:10) [138]
>
> Мораль данного примера состоит в том, что код с исключениями
> надо писать с учетом того, что исключение может возникнуть
> практически в любой строке кода. В частности, даже при банальном
> вызове TObject.Create может возникнуть исключение EOutOfMemory
>
Паранойя. (Но только LVT относится к ней с юмором :)
Имхо.
Плюс "перебор". Тоже имхо.
← →
Игорь Шевченко © (2010-03-06 02:41) [145]Eraser © (06.03.10 02:35) [142]
> если в программе где-то портится память, то там уже никакая
> обработка исключений не спасет
Она не портится, ее просто не хватает.
В ряде случаев обработка вполне может спасти.
> в случае же TFileStream.Create исключение - это вполне штатное
> поведение
Что есть "штатное": Не смог открыться файл в режиме fmOpen (прав не хватает) - это штатное исключение ?
Не смог создаться файл в режиме fmCreate (нет места на диске) - это штатное и ожидаемое исключение ?
Чем отличается от нехватки памяти ?
или наличие слова raise в конструкторе смущает незрелые умы и они готовы делать стойку: Ага, Борланд нарушил пятнадцатую суру Корана!
Так в ряде случаяв наличие raise лучше, чем его отсутствие.
← →
Аноним © (2010-03-06 02:43) [146]
> Германн © (06.03.10 02:41) [144]
шизофазия?
← →
Игорь Шевченко © (2010-03-06 02:53) [147]Кстати, о параметрах, цитата:
"Минимизируйте число параметров, передаваемых в метод, или, что еще важнее, передавайте только те параметры, которые нужны для поддержания абстракции, формируемой интерфейсом метода"
Стив МакКоннел, "Совершенный код".
То есть, в конструктор имеет смысл передавать те параметры, без которых создаваемый объект не имеет смысла.
← →
Германн © (2010-03-06 03:15) [148]
> Игорь Шевченко © (06.03.10 02:53) [147]
>
> Кстати, о параметрах, цитата:
>
> "Минимизируйте число параметров, передаваемых в метод, или,
> что еще важнее, передавайте только те параметры, которые
> нужны для поддержания абстракции, формируемой интерфейсом
> метода"
>
> Стив МакКоннел, "Совершенный код".
>
> То есть, в конструктор имеет смысл передавать те параметры,
> без которых создаваемый объект не имеет смысла.
>
> не ясна мораль данного примера, в контексте дискуссии данной
> ветки.
← →
Германн © (2010-03-06 03:17) [149]Похоже кто-то стремится попасть в мой черный список.
Я сей список уже почти забыл, но только почти. :)
← →
Eraser © (2010-03-06 04:13) [150]> [145] Игорь Шевченко © (06.03.10 02:41)
> Что есть "штатное":
это значит, что ожидаемое.
то есть при открытии файла мы знаем, что в TFileStream.Create может произойти исключение. соотвественно, можно заранее это предусмотреть, добавив обработчик исключения.
> Чем отличается от нехватки памяти ?
тем, что, в общем случае, не известно где оно появится и появится ли вообще.
EOutOfMemory - это кривая архитектура или, что чаще, ошибка в программе. обычно после такого исключения лучше завершить работу приложения.
← →
@!!ex © (2010-03-06 07:02) [151]> [147] Игорь Шевченко © (06.03.10 02:53)
Эм. Ну собственно и я о том же.
← →
GrayFace © (2010-03-06 07:46) [152]Alkid © (05.03.10 20:45) [106]
Это опасная возможность. Так что я всячески выступаю против нее, тем более, что есть средства избежать необходимости так делать.
Какие средства? По-моему, только одно - делать в конструкторах лишь базовую инциализацию.
(под перегрузкой в примере я имел в виду override)
1) Вызов виртуальных методов. В чем опасность?
Если бездумно написать вызов виртуального метода - в C++ будет [102], в Delphi может получиться [68]. Если писать обдуманно, то опасности не будет. В Delphi перед вызовом F будет выполнен виртуальный конструктор/инициализватор, который будет override"нут в предке, чтобы инициализироватьmessage
. Т.е. подходы C++ и Delphi в данном аспекте я считаю одинаково опасными/безопасными.
2) Вызов методов предка до вызова его конструктора. Опасность очевидна, лучше так не делать без явной необходимости.
Eraser © (05.03.10 23:33) [124]
вот так нельзя, если есть явная опасность исключения, например в TFileStream.Create (один из немногих примеров такого типа, который часто попадается в жизни).
в этом случае нужно городить лишний обработчик исключения.
а убери они открытие/создание файла в Init. Можно было бы использовать стандартный подход.
FS := TFileStream.Create();
try
FS.Init(file, mode);
finally
FS.Free;
end;
хорошим тоном было бы сделать и такой тип конструктора, на то и придумана overload.
Че-то я не понимаю. Может речь о наоборот? Что вместоFS := TFileStream.Create(file, mode)
в случае Init пришлось бы городить обработчик исключений?
← →
Вася (2010-03-06 09:25) [153]
> Че-то я не понимаю. Может речь о наоборот? Что вместо FS
> := TFileStream.Create(file, mode) в случае Init пришлось
> бы городить обработчик исключений?
>
Вроде как два примера абсолютно равнозначны, вариант с Init просто длиннее на один вызов (этого самого Init), целесообразность мягко говоря сомнительна
← →
@!!ex © (2010-03-06 09:48) [154]> [153] Вася (06.03.10 09:25)
У этого самого Init легко делается обработчик исключений.
В то время как для обработки исключения Create как раз и придется городить огород
← →
@!!ex © (2010-03-06 09:50) [155]> Че-то я не понимаю. Может речь о наоборот? Что вместо FS
> := TFileStream.Create(file, mode) в случае Init пришлось
> бы городить обработчик исключений?
Покажи как грамотно обработать исключение вызванное в Create
← →
Kerk © (2010-03-06 10:31) [156]
> Игорь Шевченко © (06.03.10 02:53) [147]
>
> Кстати, о параметрах, цитата:
>
> "Минимизируйте число параметров, передаваемых в метод, или,
> что еще важнее, передавайте только те параметры, которые
> нужны для поддержания абстракции, формируемой интерфейсом
> метода"
>
> Стив МакКоннел, "Совершенный код".
>
> То есть, в конструктор имеет смысл передавать те параметры,
> без которых создаваемый объект не имеет смысла.
Ну дык ежу понятно, что если для инициализации класса нужно 3 параметра, то совсем не обязательно в конструктор передавать их 10.
← →
KSergey © (2010-03-06 10:38) [157]> Игорь Шевченко © (05.03.10 15:58) [62]
> > Речь про штатное поведение дельфи.
> Штатным поведением Delphi запрещено перекрывать NewInstance ?
Не запрещается. Но делающий это человек должен четко понимать что в перекрытом методе он должен сделать.
Либо написать красными крупными буквами: "я подложил вам всем свинью, поэтому удобства и приятные плюшки дельфи типа Free - не работают".
Если он и этого не напишет - то это уже будет квалифицироваться как говнецо.
← →
Piter © (2010-03-06 11:58) [158]@!!ex © (06.03.10 9:50) [155]
Покажи как грамотно обработать исключение вызванное в Create
а чем оно отличается от обработки исключения вызванного в Init?
Если ты предполагаешь что это за исключение - так по его типу обработаешь его, независимо от того, в Create или Init оно произошло. Если неожиданное исключение - оно будет отработано вышестоящим общим обработчиком исключений.
← →
DVM © (2010-03-06 13:05) [159]
> @!!ex © (06.03.10 09:48) [154]
> > [153] Вася (06.03.10 09:25)
>
> У этого самого Init легко делается обработчик исключений.
>
> В то время как для обработки исключения Create как раз и
> придется городить огород
>
>
Нет никакой разницы
← →
Вася (2010-03-06 13:05) [160]
> @!!ex © (06.03.10 09:48) [154]
>
> > [153] Вася (06.03.10 09:25)
>
> У этого самого Init легко делается обработчик исключений.
>
> В то время как для обработки исключения Create как раз и
> придется городить огород
не придется ничего городить.
в 99 процентах случаев такое исключение просто пропускается дальше, и ответственность за него возлагается на вызывающую сторону
> KSergey © (06.03.10 10:38)
> "я подложил вам всем свинью, поэтому удобства и приятные
> плюшки дельфи типа Free - не работают".
каким образом перекрытие NewInstance может привести к неработе именно Free как плюшки? Не очень ясно
Страницы: 1 2 3 4 5 6 вся ветка
Форум: "Прочее";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
Память: 0.83 MB
Время: 0.083 c