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

Вниз

Экземпляр класса в качестве свойства другого класса   Найти похожие ветки 

 
DeScriptor   (2004-07-22 19:40) [0]

Можно ли делать сабж? То есть, иными словами, так:

TMyClass1=class
 public
   AnyProperty: TMyClass2;

Я попытался использовать подобную конструкцию (с той лишь разницей, что используется динамический массив экземпляров), и компилятор ничего плохого в том не заметил, но почему-то во время выполнения попытка создать экземпляр класса приводит к Access Violation. =(
Создаю я экземпляр следующим образом (type TClassArray=array ofTMyClass2; var ExArray: TClassArray;):

...
ExArray[i]:=TMyClass1.Create; // Здесь и происходит AV
...


Я подозреваю невозможность так поступать потому, что массив классов (такой же) работает в другом месте, создается вне класса, просто как переменная.


 
DeScriptor   (2004-07-22 19:42) [1]

P.S. Опечатался:

...
ExArray[i]:=TMyClass2.Create; // Здесь и происходит AV
...


 
Суслик ©   (2004-07-22 19:44) [2]

уверен,
1. что у тебя отключен rangecheck error в опциях проекта.
2. ты не делаешь setlength для exarray


 
AlexG ©   (2004-07-22 23:51) [3]

Действительно, проверь то о чем тебе говорит Суслик.
PS: Пока Кролик с Вини-Пухом не пришли, лучше ешь мёд... Пятачок тебе не помешает :Р


 
DeScriptor   (2004-07-23 01:52) [4]

Ну, все-таки я, наверное, не настолько тупой, чтобы писать в массив, длина которого не задана! =) Просто, я подумал, что это здесь писать будет излишне. Да и range-checking у меня всегда включен, т.к. я прекрасно знаю свою слабость ошибаться на единичку. Так что, проблема в чем-то другом.


 
ЮЮ ©   (2004-07-23 04:55) [5]

>Ну, все-таки я, наверное, не настолько тупой ...

А мы, к сожалению, не настолько умны, чтобы увидеть причмну AV, глядя на TMyClass2.Create; Приведи тогда код конструктора.

 P.S. А по поводу Subj-а. Ради бога. Тип полей может быть каким укодно из известных в этом модуле
 P.P.S. Вот только поля, IMHO, должны находиться в private, а не в public секции


 
АлексейК   (2004-07-23 06:44) [6]


type
TMyClass1=class
public
  AnyProperty: TMyClass2;
...
end;
TClassArray=array ofTMyClass2;
var ExArray: TClassArray;

...
ExArray[i]:=TMyClass1.Create; // Здесь и происходит AV
P.S. Опечатался:

ExArray[i]:=TMyClass2.Create; // Здесь и происходит AV
В таком случае причем тут TMyClass1? Следовательно вопрос становися непонятным, какое отношение имеет к нему тип поля объекта?

Поробуйте так.
ExArray[i]:=nil;
Если ошибка возникает и память под массив выделена была, то скорее всего происходит банальный выход за пределы диапазона массива.


 
Ega23 ©   (2004-07-23 09:42) [7]

ИМХО, порочный путь использовать динамический массив классов. Используй TObjectList.


 
Суслик ©   (2004-07-23 11:18) [8]

автор, у тебя нет другого выхода, кроме как расколоться и привести полный текст tmyclass1.create


 
DeScriptor   (2004-07-23 14:52) [9]

Ну, что ж, приведу весь код ОДНОГО класса (в котором баг происходит, в моем примере выступал в роли TMyClass1, тот, что я образно обозвал TMyClass2, работает без проблем вообще).

unit ResProcessingCode;

interface

uses
 Classes, ResHeaderClassCode, SysUtils;

const
 RP_SCAN=Byte(1);
 RP_EXTR=Byte(2);
 RP_PACK=Byte(3);

type
 TEntriesListElement=record
   Offset:longword;
   Extension:string[8];
 end;
 THdrArray=array of TResHeader;

 TResProcessing = class(TThread)
 private
   EntriesList: array of TEntriesListElement;
   EntriesFile: file of TEntriesListElement;
   HeadersList: THdrArray;
   ResFile:file;
   LastBarPos, CurBarPos:word;
   CurFilePos, MaxFilePos:longword;
   LogEvent:string;
   procedure ScanResFile();
   procedure ExtractFiles();
   procedure PackFiles();
   procedure UpdateProgBar();
   procedure UpdateLog();
 public
   JobID:byte;
   procedure SetHeadersList(HeadersToProcess: THdrArray);
   procedure ResetEngine(FileName:string; HeadersToProcess: THdrArray);
   constructor Create(FileName:string; HeadersToProcess: THdrArray);
   destructor Destroy(); override;
 protected
   procedure Execute(); override;
 end;

implementation
uses MainWinCode;

procedure TResProcessing.UpdateLog();
begin
 MainWinCode.UpdateLog(LogEvent);
end;

procedure TResProcessing.ResetEngine(FileName:string; HeadersToProcess: THdrArray);
begin
 JobID:=RP_SCAN;
 if EntriesList<>nil then EntriesList:=nil;
 SetHeadersList(HeadersToProcess);
 AssignFile(ResFile,FileName);
 Reset(ResFile,1);
 MaxFilePos:=FileSize(ResFile);
 CurBarPos:=0;
 Synchronize(UpdateProgBar);
end;

procedure TResProcessing.UpdateProgBar();
begin
 LastBarPos:=CurBarPos;
 CurBarPos:=trunc((CurFilePos*MainWin.JobProgress.Width)/MaxFilePos);
 if CurBarPos<>LastBarPos then MainWin.JobProgress.Position:=CurBarPos;
end;

procedure TResProcessing.SetHeadersList(HeadersToProcess: THdrArray);
var i:integer;
   CRRes:boolean;
begin
 SetLength(HeadersList, High(HeadersToProcess));
 for i:=0 to High(HeadersToProcess) do begin
   HeadersList[i]:=TResHeader.Create(HeadersToProcess[i].HRDFileName,CRRes); //ЗДЕСЬ ПРОИСХОДИТ VA!!!!
   if CRRes then HeadersList[i]:=HeadersToProcess[i];
 end;
end;

procedure TResProcessing.ScanResFile();
var j,k,DataDone, DataOverlay, swapoffset:integer;
   DataBuff: T8BitData;
   LocalEntries: T16Bitdata;
   a,b,ArrLength:word;
   swapextens:string[4];
begin
 DataOverlay:=0;
 DataDone:=65536;
 for j:=0 to High(HeadersList) do if Length(HeadersList[j].HeadData)>DataOverlay then DataOverLay:=Length(HeadersList[j].HeadData);
 while not eof(ResFile) do begin
   if High(DataBuff)<>DataDone then SetLength(DataBuff,DataDone);
   BlockRead(ResFile,DataBuff[0],65536,DataDone);

   for j:=0 to High(HeadersList) do begin
     if HeadersList[j].SeekSelf(DataBuff,LocalEntries) then begin
       SetLength(EntriesList,Length(EntriesList)+Length(LocalEntries));
       for k:=0 to High(LocalEntries) do begin
         EntriesList[Length(EntriesList)-Length(LocalEntries)+k].Offset:=LocalEntries[k]+FilePos(ResFile)-DataDone;
         EntriesList[Length(EntriesList)-Length(LocalEntries)+k].Extension:=HeadersList[j].ResExt;
         LogEvent:=HeadersList[j].ResName+" found at offset "+IntToStr(FilePos(ResFile))+".";
         Synchronize(UpdateLog);
       end;
     end;
   end;

   Seek(ResFile,FilePos(ResFile)-DataOverlay);
   CurFilePos:=FilePos(ResFile);
   Synchronize(UpdateProgBar);
 end;
 ArrLength:=High(EntriesList);
 for a:=ArrLength-2 downto 1 do
   for b:=ArrLength-1 to ArrLength-a do
     if EntriesList[b].Offset>EntriesList[b+1].Offset then begin
       swapoffset:=EntriesList[b+1].Offset;
       swapextens:=EntriesList[b+1].Extension;
       EntriesList[b+1].Offset:=EntriesList[b].Offset;
       EntriesList[b+1].Extension:=EntriesList[b].Extension;
       EntriesList[b].Offset:=swapoffset;
       EntriesList[b].Extension:=swapextens;
 end;
end;

procedure TResProcessing.ExtractFiles();
begin
 if (JobID<>RP_SCAN) and (EntriesList=nil) then exit;
end;

procedure TResProcessing.PackFiles();
begin
 if (JobID<>RP_SCAN) and (EntriesList=nil) then exit;
end;

destructor TResProcessing.Destroy();
begin
 CloseFile(ResFile);
 HeadersList:=nil;
 EntriesList:=nil;
end;

constructor TResProcessing.Create(FileName:string; HeadersToProcess: THdrArray);
begin
 inherited Create(True);
 ResetEngine(FileName,HeadersToProcess);
end;

procedure TResProcessing.Execute();
begin
 case JobID of
   RP_SCAN: ScanResFile();
   RP_EXTR: ExtractFiles();
   RP_PACK: PackFiles();
 end;
end;

end.


 
Ega23 ©   (2004-07-23 14:57) [10]

1. Что такое TResHeader?
2. Чему равно HeadersToProcess[i]?
3. Может вместо того, чтобы в динамических массивах хранить объекты воспользуешься стандартным TObjectList?


 
Sandman25 ©   (2004-07-23 15:03) [11]

Нет inherited destroy
Нет const перед параметрами-массивами
SetLength(HeadersList, High(HeadersToProcess)+1);
или Length.


 
Subdigger ©   (2004-07-23 15:06) [12]

памому сдесь нада до High(HeadersToProcess)-1
for i:=0 to High(HeadersToProcess) do begin
  HeadersList[i]:=TResHeader.Create(HeadersToProcess[i].HRDFileName,CRRes); //ЗДЕСЬ ПРОИСХОДИТ VA!!!!
  if CRRes then HeadersList[i]:=HeadersToProcess[i];
end;


 
Subdigger ©   (2004-07-23 15:09) [13]

... а еще  твоя фича  High(HeadersToProcess) делает масив на 1 меньше єто так нада?

и почему например не так length(HeadersToProcess) или length(HeadersToProcess)-1


 
VMcL ©   (2004-07-23 15:33) [14]

>>DeScriptor  (23.07.04 14:52) [9]

procedure TResProcessing.SetHeadersList(HeadersToProcess: THdrArray);
var i:integer;
 CRRes:boolean;
begin
SetLength(HeadersList, Length(HeadersToProcess));
for i:=0 to High(HeadersToProcess) do begin
 HeadersList[i]:=TResHeader.Create(HeadersToProcess[i].HRDFileName,CRRes); //ЗДЕСЬ ПРОИСХОДИТ VA!!!!
 if CRRes then HeadersList[i]:=HeadersToProcess[i];
end;
end;


?


 
DeScriptor   (2004-07-23 17:38) [15]

Да...... Много всего понаписали, огромное спасибо!
А в итоге правы оказались те, кто советовал юзать Length или High+1: я, как и всегда, запутался с единичкой!
Ну, почему нельзя было сделать все массивы одинаковыми?! Почему именно самые полезные - динамические, должны начинаться с 0 индекса?!.


 
Sandman25 ©   (2004-07-23 17:39) [16]

[15] DeScriptor   (23.07.04 17:38)

Все массивы начинаются с нуля :)


 
DeScriptor   (2004-07-23 21:29) [17]

Разве? А если я создаю его примерно так:
MyArray: array[1...10] of byte;
Разве первым индексом не будет 1?..


 
VML   (2004-07-25 13:09) [18]

>>DeScriptor  (23.07.04 17:38) [15]

>Ну, почему нельзя было сделать все массивы одинаковыми?! Почему именно самые полезные - динамические, должны начинаться с 0 индекса?!.

Потому что он нуля удобнее и быстрее рассчитывать смещение в памяти от начала массива.

>>DeScriptor  (23.07.04 21:29) [17]

>Разве первым индексом не будет 1?..

Формально, да.


 
VMcL ©   (2004-07-25 13:10) [19]

>>DeScriptor  (23.07.04 17:38) [15]

>Ну, почему нельзя было сделать все массивы одинаковыми?! Почему именно самые полезные - динамические, должны начинаться с 0 индекса?!.

Потому что он нуля удобнее и быстрее рассчитывать смещение в памяти от начала массива.

>>DeScriptor  (23.07.04 21:29) [17]

>Разве первым индексом не будет 1?..

Формально, да.



Страницы: 1 вся ветка

Текущий архив: 2004.08.08;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.047 c
6-1086710125
ev
2004-06-08 19:55
2004.08.08
подсчет контрольных сумм


8-1085322269
Sanek_metaller
2004-05-23 18:24
2004.08.08
Как загрузить SWF из DLL?


14-1090736418
Суслик
2004-07-25 10:20
2004.08.08
Отпуск


3-1089748306
Bizon's
2004-07-13 23:51
2004.08.08
Проблемы UDF


14-1090243869
Baron
2004-07-19 17:31
2004.08.08
Интересный САБЖ