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

Вниз

Работа с динамическим массивом объектов   Найти похожие ветки 

 
Jaguar   (2002-05-16 11:41) [0]

Добрый утро/день/вечер/ночь Мастерам!
Делаю приблизительно так:

var List:TMonstrList;
begin
...
SetLength(List.FList, 1);
//длина нормально задается, становится равной 1
List.Flist[0]:=TMonstr.Create;
...
end;

(Для добавления в модуле есть свои процедуры, однако через них такой же результат, думал в них дело, поэтому еще так пробовал)
Вроде как создал объект, однако при дальнейшей попытке обратиться к полям этого объекта вываливается ошибка AccessViolation. Кто-нибудь может подсказать, в чем залючается кривость моих рук?
И другой вопрос: создаю отдельный экземпляр TMonstr. Присваиваю его полям какое-то значение, уничтожаю его - никаких ошибок нет. Закрываю программу - она закрывается, однако выдает сообщение Stack overflow. Почему при закрытии программы и почему вообще выдает - не могу понять.
И третий вопрос, опять же по этим структурам. К тому самому массиву FList добавляю три элемента путем таких вот действий:

SetLength(List.FList, List.Length+1);
List.Flist[List.High]:=TMonstr.Create;

После того, как создается третий объект, программа вываливается с ошибкой, которую Delphi даже не ловит. В чем тут дело - опять же не могу понять. Если кто-то сможет помочь советом - очень прошу.

(Ниже приводится полный текст модуля-описания этих самых объектов)


 
Jaguar   (2002-05-16 11:43) [1]


unit uMonstrType;

interface

uses uUtils, SysUtils;

type

TDiceType=(d4, d6, d8, d10, d12, d20, d100);

TDmgType=( dtKnife, dtBlade, dtAxe, dtMace, dtPike, dtThrow, dtShoot, dtHand,
dtFire, dtAir, dtEarth, dtWater, dtAstral, dtLife, dtDeath, dtLight, dtDark);

TMonstrAttack = record
Name: String[40];
Attack: integer;
AP: integer;
SHKU: integer;
SHKP: integer;
Range: integer;
DmgCount: integer;
DmgDice: TDiceType;
DmgBonus: integer;
DmgType: TDmgType;
end;

TMonstr = class
public

Code: integer;
Name: string; // название (используется в интерфейсе)
Description: string; // Описание

Level: integer;
Intellect: integer;
Perception: integer;
AP: integer;
MaxHits: integer;
MaxCrHits: integer;
MaxOtrHits: integer;
{
Hits: integer;
CrHits: integer;
OtrHits: integer;
{}
Defence: integer;
Armor: integer;
Exp: integer;

Attacks: array of TMonstrAttack;

private

function getAttackCount: integer;
function getAttack(index: integer): TMonstrAttack;
procedure setAttack(index: integer; const Attack: TMonstrAttack);
function Count:integer;//количество атак

public

procedure Init;
constructor Create; overload;
destructor Destroy; override;

// запись / сохранение
procedure LoadFrom(const F: file);
procedure SaveTo(const F: file);

function AddAttack: integer; // возвращает ИНДЕКС
procedure DelAttack(index: integer); // удаление по индексу

property AttackCount: integer read getAttackCount;
property AttackList[index: integer]: TMonstrAttack read getAttack write setAttack;
end;

TMonstrList = class
private

MaxCode: integer;

function getLow: integer;
function getHigh: integer;
function getLength: integer;
// возвращает индекс по коду
function getIndex(code: integer): integer;
// доступ по коду
procedure setDataByCode(code: integer; const MonstrData: TMonstr);
function getDataByCode(code: integer): TMonstr;
// доступ по индексу
procedure setData(i: integer; const MonstrData: TMonstr);
function getData(i: integer): TMonstr;

public

FList: array of TMonstr;

constructor Create;
destructor Destroy; override;

// добавляет элемент и возвращает указатель на него
function Add: TMonstr;
// удаляет элемент с указанным кодом
procedure Del(code: integer);
// проверяет наличие элемента с указанным кодом
function Exist(code: integer): boolean;
// очищает список
procedure Clear;

// запись / сохранение
procedure LoadFromFile(const F: file);
procedure SaveToFile(const F: file);

property Low: integer read getLow;
property High: integer read getHigh;
property Length: integer read getLength;
// доступ по коду
property Data[Code: integer]: TMonstr read getDataByCode write setDataByCode; default;
// доступ по индексу
property List[i: integer]: TMonstr read getData write setData;
end;

implementation

procedure TMonstr.Init;
begin
Code := 0;
Name := "Новый";
Description := "";
Attacks := nil;
Level := 1;
Intellect := 1;
Perception := 1;
MaxHits := 1;
MaxCrHits := 1;
MaxOtrHits := 1;
Defence := 0;
Armor := 0;
Exp := 0;
end;

constructor TMonstr.Create;
begin
inherited;
Init;
AddAttack;
end;

destructor TMonstr.Destroy;
begin
SetLength(Attacks, 0);
inherited;
end;

procedure TMonstr.SaveTo(const F: file);
var i, count: integer;
begin
end;

procedure TMonstr.LoadFrom(const F: file);
var i, count: integer;
begin
end;

function TMonstr.AddAttack: integer;
begin
SetLength(Attacks, Length(Attacks) + 1);
Attacks[Count].Name:="Атака №"+IntToStr(Count);
Attacks[Count].Attack:=1;
Attacks[Count].AP:=3;
Attacks[Count].SHKU:=0;
Attacks[Count].SHKP:=0;
Attacks[Count].Range:=1;
Attacks[Count].DmgCount:=1;
Attacks[Count].DmgDice:=d4;
Attacks[Count].DmgBonus:=0;
Attacks[Count].DmgType:=dtKnife;
AddAttack := High(Attacks);
end;

function TMonstr.getAttackCount: integer;
begin
getAttackCount := Length(Attacks);
end;

function TMonstr.getAttack(index: integer): TMonstrAttack;
begin
getAttack := Attacks[index];
end;

procedure TMonstr.setAttack(index: integer; const Attack:TMonstrAttack);
begin
Attacks[index]:=Attack;
end;

function TMonstr.Count:integer;
begin
Count:=Length(Attacks);
end;


 
Jaguar   (2002-05-16 11:44) [2]


constructor TMonstrList.Create;
begin
MaxCode := 0;
end;

destructor TMonstrList.Destroy;
var i: integer;
begin
inherited;
for i := Low to High do FList[i].Destroy;
FList := nil;
end;

function TMonstrList.getLow: integer;
begin
getLow := 0;
end;

function TMonstrList.getHigh: integer;
begin
getHigh := System.Length(FList)-1;
end;

function TMonstrList.getLength: integer;
begin
getLength := System.Length(FList);
end;

function TMonstrList.getIndex(code: integer): integer;
var i: integer;
begin
for i := Low to High do
if FList[i].Code = code then
begin
getIndex := i;
exit;
end;
getIndex := -1;
end;

procedure TMonstrList.setDataByCode(code: integer; const MonstrData: TMonstr);
var index: integer;
begin
index := getIndex(code);
if (index = -1) then exit;
FList[index].Create(MonstrData);
end;

function TMonstrList.getDataByCode(code: integer): TMonstr;
var index: integer;
begin
index := getIndex(code);
if (index = -1) then getDataByCode := nil
else getDataByCode := FList[index];
end;

procedure TMonstrList.setData(i: integer; const MonstrData: TMonstr);
begin
if (i < Low) or (i > High) then exit;
FList[i].Create(MonstrData);
end;

function TMonstrList.getData(i: integer): TMonstr;
begin
if (i < Low) or (i > High) then getData := nil
else getData := FList[i];
end;

function TMonstrList.Add(): TMonstr;
begin
MaxCode := MaxCode + 1;
SetLength(FList, Length + 1);
FList[High] := TMonstr.Create;
FList[High].Code := MaxCode;
FList[High].Name := "Монстр №"+IntToStr(Flist[High].Code);
Add := FList[High];
end;

end.


 
Deus   (2002-05-16 11:44) [3]

может, так надо:
var List:array of TMonstrList;


 
Coalycat   (2002-05-16 13:09) [4]

По-моему для хранения объектов лучше использовать TList


 
softland   (2002-05-16 13:27) [5]

Полагаю надо перейти от использования

FList: array of TMonstr;

к использованию списка TList отнаследовав от него свой класс и переопределив методы Get и Put для работы с TMonstr.
Можно воспользоваться TStringList и его полем Objects - это удобней поскольку содержимое поля Strings может служить средством идентификации и поиска по списку.
Примерно так:

* Класс для хранения одного поля заголовка LAS файла
При разборе секции ~WELL парсим каждую линию и в сохраняем результат в
объекте данного класса. *)
THeaderRec = class (TObject)
public
//имя поля
id : string;
//ед измерения
aUnit : string;
//значение
value : string;
//коментарий
comment : string;
//возвращает значение как реальное число
function asFloat : double;
//возвращает значение как текст
function asString : string;
end;


(* Класс для хранения строк заголовка LAS файла
в Strings храним идентификатор поля: STRT, API, и тд.
в поле Object заносим объекты класса THeaderRec *)
TLASHeaderList = class(TStringList)
public
// Вызывает конструктор предшественика
constructor Create;
// Вызывает деструктор предшественика
destructor Destroy; override;
// Добавляет параметр с именем name ед. измерения _aUnit и значением value
function AddItem(const name, _aUnit, value : string ): integer;
// Возвращает ед. измерения данного параметра в виде строки}
function GetUnit(const index : string) : string;
// Устанавливает ед. измер параметра}
procedure SetUnit(const index : string; const strUnit : string);
// Возвращает значение параметра с именем index в виде строки}
function GetValue(const index : string) : string;
// Возвращает значение параметра с именем index в виде строки}
function asString(const index : string) : string;
// Возвращает значение параметра с именем index в виде числа}
function asFloat(const index : string) : double;
// Возвращает значение параметра с именем index в виде даты}
function asDateTime(const index : string) : TDateTime;
// Устанавливает значение параметра с именем index равным переданной строке}
procedure SetValue(const index : string; const strValue : string);
// Устанавливает значение параметра с именем index равным переданному числу}
procedure SetValueAsFloat(const index : string; aValue : double);
// Возвращает значение коментария к параметру с именем index в виде строки}
function GetComment(const index : string) : string;
// Устанавливает коментарий к параметру с именем index равным переданной строке}
procedure SetComment(const index : string; const strComment : string);
end;

Ясный пень вместо index : string можно использовать index : integer;


 
softland   (2002-05-16 13:30) [6]

Я предлогаю перейти на списки именно из-за резкого уменьшения ошибок по выделению, освобождению памяти, а твои проблемы на 99% именно в этом. А чтобы найти их придется медленно и мучительно отлаживать твой код :(



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

Форум: "Основная";
Текущий архив: 2002.05.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.006 c
7-88664
AlexRush
2002-02-28 18:17
2002.05.27
WinSock2 API - чтение данных из сокета


1-88559
Blacki
2002-05-16 15:02
2002.05.27
Проблема с ShowModal


1-88402
mifi
2002-05-16 20:34
2002.05.27
Myimage :array


8-88567
tovSuhov
2001-12-28 11:13
2002.05.27
Возвращаясь к pmNotXor...


1-88410
Lit_Bogdan
2002-05-17 00:06
2002.05.27
График типа DBChart





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