Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.08.08;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.046 c
14-1090577643
VHS
2004-07-23 14:14
2004.08.08
Ошибка при FormActivate


1-1090471679
Grayver
2004-07-22 08:47
2004.08.08
Редактирование ячейки в Excel


1-1090484163
bodia
2004-07-22 12:16
2004.08.08
Запуск из доса без переключения в Windows


4-1088251501
pantel
2004-06-26 16:05
2004.08.08
Как использовать DDE?


3-1089703549
Orac
2004-07-13 11:25
2004.08.08
Переход на сетевые БД





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