![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
как конструктору вернуть NUL? [D7, XP]
Yozj © (2006-03-01 16:09:00)Создаю класс, в конструктор передаю параметр - имя файла, как сделать так, чтобы если такого файла не существует конструктор возвращал NIL, а не ссылку на объект?
То есть, чтобы я мог провести такой трюк:
F := TMyClass.Create(path);
if F = nil then
...
else
...
Ega23 (2006-03-01 19:14:00) [1]
unit Unit2;
interface
uses SysUtils, Dialogs;
type
TMyClass=class
private
FFileName:String;
public
constructor Create(aFileName:String);
class function Init(aFileName:String):TMyClass;
end;
implementation
{ TMyClass }
constructor TMyClass.Create(aFileName:String);
begin
FFileName:=aFileName;
ShowMessage(FFileName);
end;
class function TMyClass.Init(aFileName: String): TMyClass;
begin
if not FileExists(aFileName) then Result:=nil
else
Result:=TMyClass.Create(aFileName);
end;
end.
И теперь использование:
procedure TForm1.Button1Click(Sender: TObject);
begin
MyClass:=TMyClass.Init('C:\1.bmp');
end;
Гаврила (2006-03-01 19:06:00) [2]Вдогонку
понятно ,ч то реализовать "чтобы работало" можно по разному, весь вопрос в том, как удобнее, где меньше кода.
вариант "nil" предполагает необходимость вставки дополнительной проверки на nil во всех местах, где вызывается конструктор.
Например, ты не передаешь путь в конструктор, а присваиваешь проперти.
Опять же - как сигнализировать вызывающей стороне об ошибке "нет файла"?
- либо опять через исключение
(а не проще тогда поместить его в конструктор? тем более что если этот класс не имеет смысла без связки с нормальным существующим файлом, то при таком раскладе в тот период времени ,когда он уже создан, но свосйстов еще не присвоено, но являет собой достаточно странную сущность и работать не может. Потенциально это ведел к ошибкам)
- Либо через какие-то булевские флаги
это будет опять требовать вставки дополнительных проверок снаружи - то есть приведет к дублированию кода и вероятности неправильного использования класса
Гаврила (2006-03-01 18:49:00) [3]
> Yozj ©
> Использовать исключение в конструкторе тоже плохо, по
> отношению к программисту (даже ко мне самому), который
> этот класс будет использовать...
Полагаю что наоборот.
Два варианта (предположим что класс используешь не ты)
1. В конструкторе осмысленное исключение
"файл такой-то не найден"
программист сразу получает его и понимает в чем дело. Он может его даже не обрабатывать секцией Except- выполнение кода прервется ,стек очистится, и если ни одной секции Except не встретится, уже пользователь получит MessageBox с текстом исключения, из которого понятно, в чем, собственно, дело.
2. конструктор вернул nil (предположим что это реализовано)
программист создал объект, обращается к нему дальше и получае Access Violation.
"В чем дело... надо разбираться, лазить по чудому коду, читать документацию".
Предположим что он (другой программист) знает, что твой конструктор может вернуть nil.
и это означает что произошла ошибка... а какая? нет файла? а может быть другая какая-нибудь, например файл есть, но он поврежден.
Как их отличить между собой?
Ega23 (2006-03-01 18:38:00) [4]Ха. Можно хитрее. Через class procedure
Yozj (2006-03-01 18:35:00) [5]Ради интереса попытался поработать с методом NewInstance, решил его не трогать. Использовать исключение в конструкторе тоже плохо, по отношению к программисту (даже ко мне самому), который этот класс будет использовать... значит действительно самое простое использовать проперти.
Всем спасибо!
Yozj (2006-03-01 18:35:00) [6]Ради интереса попытался поработать с методом NewInstance, решил его не трогать. Использовать исключение в конструкторе тоже плохо, по отношению к программисту (даже ко мне самому), который этот класс будет использовать... значит действительно самое простое использовать проперти.
Всем спасибо!
Гаврила (2006-03-01 18:13:00) [7]Концептуально правильно поднимать исключение.
Объект будет разрушен автоматически (при исключении в конструкторе).
Если все таки нужно вернуть nil
то нужно перекрыть метод NewInstance (вернуть в нем то, что считаешь нужным)
но за последствия отвечать будешь самостоятельно
Ega23 (2006-03-01 17:04:00) [8]Не передавай его в конструктор, заведи property и не мучайся.
Сергей М. (2006-03-01 16:32:00) [9]constructor TMyClass.Create(path);
begin
if ФайлНеСуществует(path) then
raise Exception.Create('Файл не существует !');
...
inherited [Create(...)];
...
end;
...
F := nil;
try
F := TMyClass.Create(path);
except
end;
if F = nil then
...
else
...
Сергей М. (2006-03-01 16:28:00) [10]Считай что никак.
DesWind (2006-03-01 16:11:00) [11]Можно по аналогии TFileStream генерить ошибку в конструкторе.