Форум: "Основная";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];
Внизописание динамического массива в классе Найти похожие ветки
← →
serj (2004-11-13 19:50) [0]описывается класс
TDTable = class(TObject)
public
Cells : array of array of integer;
...
end;>
var
XD : TDTable;
begin
XD.Create;
при создании объекта происходит ошибка с сообщением debugger"a
Project Project1.exe raised exception class EAccessViolation whith message "Access violation at address 00404E80 in module "Project1.exe".Read of address 00000000C
может кто знает, в чём тут дело?
← →
Palladin © (2004-11-13 19:52) [1]да тут наверное все знают в чем тут дело...
← →
тт (2004-11-13 20:00) [2]Попробуй
XD:=TDTable.Create;
← →
Piter © (2004-11-13 20:22) [3]Конструктор вызывается через ссылку на класс, а не экземпляр класса...
Да и неужели ты не знаешь, что нельзя вызывать методы у экземпляра, который еще не создан (уже унчтожен)?
← →
GuAV © (2004-11-13 20:31) [4]Piter © (13.11.04 20:22) [3]
Конструктор вызывается через ссылку на класс, а не экземпляр класса...
Не всегда.
← →
begin...end © (2004-11-13 20:34) [5]Piter © (13.11.04 20:22) [3]
Конструктор можно вызвать и после создания экземпляра.
← →
serj (2004-11-13 21:41) [6]да, ребят, это я уже конкретно стормозил...
← →
Гаврила © (2004-11-13 22:16) [7]
> [5] begin...end
> Конструктор можно вызвать и после создания экземпляра.
Можно конечно, и все сработает. Но я бы за такое расстреливал :-)))
← →
GuAV © (2004-11-13 22:35) [8]2 Гаврила ©
Смотрите метод TApplication.CreateForm, который обычно вызывается из dpr. Вы хотите растрелять автора VCL ? :-)
← →
Гаврила © (2004-11-13 22:41) [9]
> [8] GuAV
Пусть в меня полетят камни... Но за это метод - можно и расстрелять
← →
Piter © (2004-11-14 03:15) [10]GuAV © (13.11.04 20:31) [4]
Не всегда
а можно корректный пример, когда это не так?
← →
Германн © (2004-11-14 03:23) [11]2 Piter © (14.11.04 03:15) [10]
Может я и не прав. Но, имхо, конструктор объекта выполняет две функции: Создание и Инициализация. А "Инициализация", иногда, нужна без создания.
← →
jack128 © (2004-11-14 03:55) [12]Piter © (14.11.04 3:15) [10]
Внимательно читаем [8] ;-)
← →
GuAV © (2004-11-14 13:31) [13]Германн © (14.11.04 3:23) [11]
А "Инициализация", иногда, нужна без создания.
Только эта... конструктор всё равно прибьёт недосозданный объект, даже при инициализации... в Borland специально постарались чтоб было именно так...
2 jack128 © а почему бы не поговорить об этом ещё раз ;-)
← →
GuAV © (2004-11-14 13:33) [14]GuAV © (14.11.04 13:31) [13]
конструктор всё равно прибьёт недосозданный объект
под "недосозданым" объектом понимался вызов конструктора в котором произошло исключение.
← →
Piter © (2004-11-14 14:48) [15]jack128 © (14.11.04 3:55) [12]
Внимательно читаем [8] ;-)
А, ну да... А зачем так сделано?
← →
jack128 © (2004-11-14 15:31) [16]GuAV © (14.11.04 13:31) [13]
2 jack128 © а почему бы не поговорить об этом ещё раз ;-)
:-) Свою позицию я не изменил.
Piter © (14.11.04 14:48) [15]
ну да... А зачем так сделано?
В данном случае - хз. Могу привести случай, чде подобный алгоритм создания оправдан:function TReader.ReadComponent(Component: TComponent): TComponent;
...
Result := TComponent(ComponentClass.NewInstance);
if ffInline in Flags then // до вызова конструктора нужно выставить флаги
begin
Include(Result.FComponentState, csLoading);
Include(Result.FComponentState, csInline);
end;
try
Result.Create(Owner);
except
Result := nil;
raise;
end;
← →
Defunct © (2004-11-14 15:34) [17]jack128 © (14.11.04 03:55) [12]
> Внимательно читаем [8] ;-)
А что там внимательно читать?
Piter прав, то что в [8] не есть пример вызова конструктора:
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
> а можно корректный пример, когда это не так?
нет такого примера, кроме случая когда используется тип Object.
Type TLalala = Object
Constructor Create;
End;
var Lalala : TLalala;
begin
lalala.Create;
end.
← →
jack128 © (2004-11-14 15:37) [18]Defunct © (14.11.04 15:34) [17]
а заглянуть в исходники CreateForm вы, конечно, не догадались? ;-)
← →
Defunct © (2004-11-14 15:50) [19]jack128 © (14.11.04 15:37) [18]
> а заглянуть в исходники CreateForm вы, конечно, не догадались? ;-)
Конечно - нет, вы насчет этого?
Instance.Create(Self);
Вероятно, этот код никто не менял начиная с Delphi 1, он чудом работает. И в качестве корректного примера, IMHO TApplication.CreateForm не годится.
← →
GuAV © (2004-11-14 15:59) [20]jack128 © (14.11.04 15:31) [16]
В данном случае - хз.
Чтобы в OnCreate переменная Form1 была валидной.
Как сказал тогда Роб, ты можешь оспаривать достоинаства этого требования, но VCL работает именно так.
Однако в обоих случаях можно избежать такой техники.
достакточно объявить такой конструкторconstructor TComponent.CreateAndInitInstVar(AOwner: TComponent; var Instance);
begin
TComponent(Instance):=Self;
Create(AOwner); // no classcreate call, just like calling inherited constructor
end;
← →
Piter © (2004-11-14 16:04) [21]jack128 © (14.11.04 15:31) [16]
до вызова конструктора нужно выставить флаги
а разве неправильнее какие бы то не было флаги передавать в конструктор, чтобы он уже устанавливат что надо?
А конкретно в твоем примере я не понял - нафига эти флаги устанавливать?
Defunct © (14.11.04 15:50) [19]
он чудом работает
гы, ну тут я не согласен... какое же это чудо, если все автосоздаваемые формы в приложении так создаются...
← →
GuAV © (2004-11-14 16:12) [22]Defunct © (14.11.04 15:50) [19]
он чудом работает.
Не чудом, этот случай _специально_ рассматривается в RTL. Считаю уместным процитировать здесь jack128 © :
Как известно конструктор объекта можно использовать в двух контекстах
1) как классовый метод
Instance := TMyCoolObject.Create();
2) как обычный метод
Instance.Create();
а вот код который компилятор ренерит при вызове коструктора можно разделить на три группы
1)
Instance := TMyCoolObject.Create();
в этом случае происходит вызов _ClassCreate(это влечет за собой вызов NewInstance а потом вызов собственно тела конструктора. если в конструкторе возникло исключение, то вызывается FreeInstance
2) Instance.Create();
последовательность вызовов таже, что и в первом случае, но в _ClassCreate передается флаг, указывающий на то что конструктор вызывается как обычный метод и вызова NewInstance не поисходит. Однако если в конструкторе возникло исключение, то теста на этот флаг не делается и соответственно объект уничтожается.
Instance.Create(); //если здесь возникло исключение, то Instance - уничтожается
3)
constructor TChildMyCoolObject.Create;
begin
inherited Create(); // тут происходит просто передача управления в унаследованный конструктор. Безо всяких дополнительных вызовов.
end;
Раз уже делают различия между вызовом конструктора через ссылку на объект из другого конструктора и в другом случае, то можно было бы запретить этот самый другой случай. В _очень_немногих_ случаях вроде TApplication.CreateForm пойти например по пути [20].
Defunct © (14.11.04 15:50) [19]
IMHO TApplication.CreateForm не годится
Согласен.
← →
Defunct © (2004-11-14 17:37) [23]GuAV © (14.11.04 16:12) [22]
>> Defunct © (14.11.04 15:50) [19]
>> он чудом работает.
> Не чудом, этот случай _специально_ рассматривается в RTL.
Говоря "чудом работает" я подразумевал специально сделанное исключение, сделанное для совместимости с более ранними версиями.
> _специально_
специально = исключительный случай.
← →
GuAV © (2004-11-14 20:29) [24]Piter © (14.11.04 16:04) [21]
а разве неправильнее какие бы то не было флаги передавать в конструктор, чтобы он уже устанавливат что надо?
И так кстати тоже делают.constructor TWinControl.CreateParented(ParentWindow: HWnd);
begin
FParentWindow := ParentWindow;
Create(nil);
end;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.032 c