Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.08.27;
Скачать: CL | DM;

Вниз

А я и не знал...   Найти похожие ветки 

 
Игорь Шевченко ©   (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;
Скачать: CL | DM;

Наверх




Память: 0.84 MB
Время: 0.057 c
2-1275043106
kolian
2010-05-28 14:38
2010.08.27
запоминание и воспроизведение в окне memo


15-1271261484
[true]TRIx
2010-04-14 20:11
2010.08.27
Ищу дельфи пример Цепи Маркова.


6-1224709751
serko
2008-10-23 01:09
2010.08.27
Telnet через Delphi...


2-1272386845
romario
2010-04-27 20:47
2010.08.27
Как передать данные из одной процедуры в другую


15-1275731524
REX
2010-06-05 13:52
2010.08.27
Комментарии в SQL (Access)