Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.11.28;
Скачать: CL | DM;

Вниз

описание динамического массива в классе   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.048 c
14-1100026374
Valentina
2004-11-09 21:52
2004.11.28
программа "Тест"


4-1098156661
Боян Георгиев
2004-10-19 07:31
2004.11.28
Как узнать если процес запущен


6-1095316792
Григорьев Антон
2004-09-16 10:39
2004.11.28
Не могу разобраться с параметрами WSAEnumProtocols


1-1100452965
dolphin
2004-11-14 20:22
2004.11.28
список имен файлов и папок


14-1100004423
TRyaSS
2004-11-09 15:47
2004.11.28
Кто знает C(си), помогите плз. перевести