Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
2-1269309875
r_yevgeniy
2010-03-23 05:04
2010.08.27
Сохранить данные в файл из двух компонентов StringGrid


15-1270197774
12
2010-04-02 12:42
2010.08.27
Тоже про природу. Объясните феномен.


15-1266979814
brother
2010-02-24 05:50
2010.08.27
IPv6


2-1274443627
istok
2010-05-21 16:07
2010.08.27
проблема подключения к скл2005...


2-1274159330
webpauk
2010-05-18 09:08
2010.08.27
Поиск оптимума пересмотром всех значений





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский