Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.07.09;
Скачать: [xml.tar.bz2];

Вниз

Как избежать варинига при создании объекта в try finally   Найти похожие ветки 

 
novill   (2006-05-25 11:06) [0]

если удаление объекта происходит в блоке finally, то компилятор пишет предупреждение, что объект может быть не создан.
Мне строчка эта сильно не нравится, хотя понимаю, что ничего страшного. Как надо написать чтобы ее не было?

вот пример кода
var
 SD:TSaveDialog;
begin
 try
  SD:=TSaveDialog.Create(MyForm);
  SD.InitialDir:=GetCurrentDir;
  SD.Filter:="Excel files (*.xls)|*.XLS";
  if SD.Execute then filename:=SD.FileName;
 finally
  SD.Free;
 end;

Компилятор пишет "Variable "SD" might not have been initialized"


 
Сергей М. ©   (2006-05-25 11:13) [1]

var
SD:TSaveDialog;
begin
SD:=TSaveDialog.Create(MyForm);
try
  ...
finally
 SD.Free;
end;


 
Loginov Dmitry ©   (2006-05-25 11:47) [2]

SD := nil; перед try finally


 
Kolan ©   (2006-05-25 11:48) [3]

Loginov Dmitry ©   (25.05.06 11:47) [2]
Зачем?
Сергей М. ©   (25.05.06 11:13) [1]
Это стандартная конструкция.


 
Loginov Dmitry ©   (2006-05-25 11:55) [4]

Kolan ©   (25.05.06 11:48) [3]
Зачем?


Затем, чтобы не было
"Variable "SD" might not have been initialized"


 
Kolan ©   (2006-05-25 12:14) [5]

var
SD:TSaveDialog;
begin
SD:=TSaveDialog.Create(MyForm);
try
 ...
finally
SD.Free;
end;

В этом случае предупреждения нет. И этот вариант гораздо правильнее. А
SD := nil;
try
 SD:=TSaveDialog.Create(MyForm);
 SD.InitialDir:=GetCurrentDir;
 SD.Filter:="Excel files (*.xls)|*.XLS";
 if SD.Execute then filename:=SD.FileName;
finally
 SD.Free;
end;

Вообще смысла особого не имеет. Зачем давать такие советы?


 
evvcom ©   (2006-05-25 12:25) [6]


> Затем, чтобы не было
> "Variable "SD" might not have been initialized"

Гон или как там сейчас любят говорить? Баян?


 
@BraIN ©   (2006-05-25 12:29) [7]


> Loginov Dmitry ©   (25.05.06 11:47) [2]
>
> SD := nil; перед try finally


Бред и самообман.


 
Loginov Dmitry ©   (2006-05-25 12:45) [8]

Самообмана тут нет (сам так ни разу не делал :)
А вот всякие ненужные варнинги такой способ убирает - это точно!


 
Сергей М. ©   (2006-05-25 12:50) [9]


> novill   (25.05.06 11:06)


> понимаю, что ничего страшного


Неправильно понимаешь. Именно о "страшном" предупреждает тебя компилятор.

Представь себе, что при выполнении строчки

SD:=TSaveDialog.Create(MyForm);

возникла искл.ситуация (по каким причинам - не важно).

В результате объект класса TSaveDialog не был создан, и в переменную SD не было ничего записано (при этом ее содержимое не определено)
Поскольку строчка, вызвавшая исключение, была включена в try-finally-блок, управление тут же будет передано в секцию finally этого блока, где ты пытаешься уничтожить несуществующий объект, что практически 100%-но гарантирует возникновение нового исключения (AV).

Именно об этом тебя и предупреждает компилятор.


 
Kolan ©   (2006-05-25 13:09) [10]

А вот всякие ненужные варнинги такой способ убирает - это точно!
Ненужных Warning"ов небывает. :)


 
Loginov Dmitry ©   (2006-05-25 13:11) [11]

И еще (для) [6], [7]

Не стоит быть такими категоричными. Предложенный мною способ в ран-тайме не будет НИЧЕМ отличаться от "правильного способа". Если объект не будет создан, то метод Free выполниться НОРМАЛЬНО. Так что не к чему тут разводить ...


 
Игорь Шевченко ©   (2006-05-25 13:23) [12]


> Предложенный мною способ в ран-тайме не будет НИЧЕМ отличаться
> от "правильного способа".


Пальцы жалко. И глаза.


 
Amoeba ©   (2006-05-25 13:27) [13]


> Loginov Dmitry ©   (25.05.06 13:11) [11]
> И еще (для) [6], [7]
>
> Не стоит быть такими категоричными. Предложенный мною способ
> в ран-тайме не будет НИЧЕМ отличаться от "правильного способа".
>  Если объект не будет создан, то метод Free выполниться
> НОРМАЛЬНО. Так что не к чему тут разводить

Все-же следует делать правильно, а не по твоему способу, и не запихивать создание объекта внутрь try...finally. Не стоит прививать начинающим плохой стиль программирования.


 
Loginov Dmitry ©   (2006-05-25 13:28) [14]

Игорь Шевченко ©   (25.05.06 13:23) [12]
Пальцы жалко. И глаза.


И вы туда же? Пальцы на то и пальцы, нечего их жалеть. Лучше (если сможете) укажите в чем я не прав, тогда я хоть смогу сказать пару слов в свою защиту :)))


 
Zz_   (2006-05-25 13:30) [15]

В связи с отсутствием RAII

try
  try
     try
        try
           try

по - моему хуже, чем

:= nil;
:= nil;
:= nil;
try
 create
 create
 create
finally
 free
 free
 free

Я не прав ?


 
evvcom ©   (2006-05-25 13:38) [16]


> Лучше (если сможете) укажите в чем я не прав

Ты подразумеваешь, что объект будет всегда создан. А вдруг случай [9]? Ну да, Free AV не возбудит, но и об Exception из Create твой try забудет. Тут собака и порылась. Приложение будет спокойно выполняться, думая, что все хорошо, пользователь волосы на ... рвать, материть программиста: "Почему такая фигня? Жму на кнопку, а диалог ни гу-гу!" и насиловать клавиатуру и мышку. А ты говоришь! Вот тебе и пальцы.


 
Игорь Шевченко ©   (2006-05-25 13:43) [17]

Loginov Dmitry ©   (25.05.06 13:28) [14]


> Лучше (если сможете) укажите в чем я не прав


При заданной наперед функциональности программа должна содержать минимальное количество удобочитаемых строк.


 
Игорь Шевченко ©   (2006-05-25 13:45) [18]

evvcom ©   (25.05.06 13:38) [16]


> но и об Exception из Create твой try забудет


Не забудет. Там стоит finally, который подразумевает выполнение действий в своей секции и дальнейшее возбуждение Exception"а.


 
evvcom ©   (2006-05-25 13:47) [19]

А... Да, да. Согласен.


 
Loginov Dmitry ©   (2006-05-25 13:51) [20]

evvcom ©   (25.05.06 13:38) [16]
Free AV не возбудит, но и об Exception из Create твой try забудет. Тут собака и порылась.


Это почему? Если в Create возникнет Exception, то управление сразу же перейдет в мой блок finally. Здесь все чисто, имхо.

Игорь Шевченко ©   (25.05.06 13:43) [17]
При заданной наперед функциональности программа должна содержать минимальное количество удобочитаемых строк.


Я - за! Убедили! С таким аргиментом не поспоришь :)


 
Сергей М. ©   (2006-05-25 13:57) [21]


> Если в Create возникнет Exception, то управление сразу же
> перейдет в мой блок finally


Угу ..а там SD = nil.
Лишняя проверка на SD=nil, заведомо возвращающая True - это лишнее бестолково затраченное время.


 
StriderMan ©   (2006-05-25 17:14) [22]


> Loginov Dmitry ©   (25.05.06 11:47) [2]
> SD := nil; перед try finally

совершенно правильный код
вызов FREE у объекта = nil не вызовет ошибку

очень удобная конструкция, когда создается несколько объектов, которые потом надо разрушить

например:

 obj1 := nil;
 obj2 := nil;
 try
   obj1 := TMyClass1.Create;
   obj2 := TMyClass2.Create;
   .....
 finally
   ob1.Free;
   obj2.Free;
 end;


вобщем-то единственный способ избежать еще одного try..finally. А если объектов 3? а если 10?

Постоянно таким кодом пишу
если один объект, то объект логичнее создать перед try


 
StriderMan ©   (2006-05-25 17:18) [23]


> но и об Exception из Create твой try забудет.

а вот и не забудет

Exception, появившийся между try .. finally после выполнения finally..end вылезет наружу. можете проверить.


 
@BraIN ©   (2006-05-25 17:58) [24]


> очень удобная конструкция, когда создается несколько объектов,
>  которые потом надо разрушить
>
> например:
>
>  obj1 := nil;
>  obj2 := nil;
>  try
>    obj1 := TMyClass1.Create;
>    obj2 := TMyClass2.Create;
>    .....
>  finally
>    ob1.Free;
>    obj2.Free;
>  end;


Честно говоря, я в недоумении (мягко говоря)..Просто поинтересуюсь: почему не так?


obj1 := TMyClass1.Create;
obj2 := TMyClass2.Create;
 try
   .....
 finally
   ob1.Free;
   obj2.Free;
 end;


 
Zz_   (2006-05-25 18:14) [25]

Если obj2 := TMyClass2.Create - вылетает, то ой


 
@BraIN ©   (2006-05-25 18:24) [26]

В реальной ситуации вылет obj2 говорит в первую очередь об ошибках проектирования. А все эти obj := nil — танцы с бубном. Потому и самообман.

Мое мнение.


 
Zz_   (2006-05-25 18:26) [27]

Почитайте про задачу Каргилла, вьюноша ...


 
StriderMan ©   (2006-05-25 18:46) [28]


> вылет obj2 говорит в первую очередь об ошибках проектирования

конечно, если в конструкторе вываливается Exception это совсем не гуд, однако в некоторых случаях такое может иметь место, особенно если в конструктор передаются какие-то параметры, например тот же TBlobStream.


 
jack128 ©   (2006-05-25 18:57) [29]

StriderMan ©   (25.05.06 18:46) [28]
если в конструкторе вываливается Exception это совсем не гуд

это абсолютно нормальная ситуация.


 
ANB ©   (2006-05-25 20:28) [30]


>
> obj1 := TMyClass1.Create;
> obj2 := TMyClass2.Create; // На этом операторе ловит исключение и получаем утечку памяти.
>  try
>    .....
>  finally
>    ob1.Free;
>    obj2.Free;
>  end;


ЗЫ. FreeAndNil рулит.


 
Loginov Dmitry ©   (2006-05-25 20:42) [31]

Сорри, а причем здесь FreeAndNil()?


 
Leonid Troyanovsky ©   (2006-05-25 22:21) [32]


> Loginov Dmitry ©   (25.05.06 20:42) [31]

> Сорри, а причем здесь FreeAndNil()?


Это примерно тот же костыль как и SD := nil.
Т.е., вид сзаду.

--
Regards, LVT.


 
Игорь Шевченко ©   (2006-05-25 22:22) [33]

jack128 ©   (25.05.06 18:57) [29]


> это абсолютно нормальная ситуация.


А чем она, собственно, абсолютно нормальна ? Как-то нечасто встречаются конструкторы с raise внутри...


 
Джо ©   (2006-05-25 22:27) [34]

> [33] Игорь Шевченко ©   (25.05.06 22:22)

Часто или не слишком часто, но, ИМХО, НЕнормального ничего нету. Особенно, если конструктор с параметрами.


 
Leonid Troyanovsky ©   (2006-05-25 22:31) [35]


> Игорь Шевченко ©   (25.05.06 22:22) [33]

> А чем она, собственно, абсолютно нормальна ? Как-то нечасто
> встречаются конструкторы с raise внутри...


Пуркуа бы не па?
Иногда очень удобно похерить весь креативный процесс,
особо не обременясь высвобождением внутренностей.
Т.е., пусть это деструктор думает, освобождать ли Assigned(x).

--
Regards, LVT.


 
Игорь Шевченко ©   (2006-05-25 23:26) [36]

Джо ©   (25.05.06 22:27) [34]
Leonid Troyanovsky ©   (25.05.06 22:31) [35]

Я обычно за распространенными решениями лезу в VCL. Вот распространенности такого решения я там не нашел. Плохо искал ?


 
Жуков Олег   (2006-05-26 00:56) [37]


> Игорь Шевченко ©   (25.05.06 23:26) [36]
>
>

 FileStream := TFileStream.Create("шт!@!$!@5asasdf", fmInOut);


 
Игорь Шевченко ©   (2006-05-26 09:25) [38]

Жуков Олег   (26.05.06 00:56) [37]


> TFileStream.Create("шт!@!$!@5asasdf", fmInOut);


Кстати, обработка ошибки сделана не совсем корректно - так как выдается только факт, что нельзя создать FileStream, но не выдается почему его нельзя создать.

Но я говорил про типичность решения, если ты почитаешь посты.


 
jack128 ©   (2006-05-26 12:15) [39]

Игорь Шевченко ©   (26.05.06 9:25) [38]
попытайся создать любой объект, являющий оболочкой над любым ресурсом ОС и тут же получишь исключение в конструкторе. TFileStream при отсутствии файлов, TForm при недостатке оконных ресурсов, ResurceStream при отсутствии ресурса в модуле, TBrush - при недостатке граф. ресурсов и тд и тп...


 
Игорь Шевченко ©   (2006-05-26 12:27) [40]


> TFileStream при отсутствии файлов


Получу.


> TForm при недостатке оконных ресурсов


Не получу


> TBrush - при недостатке граф. ресурсов


Не получу



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2006.07.09;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.016 c
2-1150969910
webpauk
2006-06-22 13:51
2006.07.09
Запрет открытия ссылок


1-1148482331
Aleksandr.
2006-05-24 18:52
2006.07.09
Как корректно терминировать нить с GetMessage?


3-1147329972
petvv
2006-05-11 10:46
2006.07.09
SQL запрос


15-1149586462
pavel_guzhanov
2006-06-06 13:34
2006.07.09
Возникла необходимость ознакомиться с Oracle


1-1148915316
webpauk
2006-05-29 19:08
2006.07.09
WebBrowser EM_SCROLL





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский