Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
4-1097669285
sw
2004-10-13 16:08
2004.11.28
сменить курсор у static a.


3-1099281373
КаПиБаРа
2004-11-01 06:56
2004.11.28
Как в FB организовывают связь Мастер-Детал?


4-1098041108
AlexeyM
2004-10-17 23:25
2004.11.28
перехват вызова Win api в другом приложении


14-1100242960
NewMan777
2004-11-12 10:02
2004.11.28
TDBF


14-1100034968
Cerberus
2004-11-10 00:16
2004.11.28
Предлогаю альтернотиву





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