Форум: "Основная";
Текущий архив: 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.55 MB
Время: 0.01 c