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

Вниз

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

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

Наверх




Память: 0.5 MB
Время: 0.018 c
1-88434
Бывалый
2002-05-17 12:11
2002.05.27
TAdvStringGrid - центрирование ячеек.


14-88613
Satrap
2002-04-17 09:38
2002.05.27
MSDN


1-88451
Димок
2002-05-17 16:33
2002.05.27
Как изменить раскладку клавиатуры в чужом окне?


3-88327
Vika2
2002-04-29 15:45
2002.05.27
Приложение Клиент - Сервер по технологии Midas


3-88328
RedKat
2002-04-29 18:10
2002.05.27
Создание DSN