|
Вопрос # 4 649/ вопрос открыт / |
|
Приветствую, уважаемые эксперты!
Подскажите пжлста в чем ошибка? Вылетает в обозначенной строке
Приложение: Переключить в обычный режим- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls;
-
- type
- TForm1 = class(TForm)
- Button1: TButton;
- Memo1: TMemo;
- procedure Button1Click(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- //
- TMyClass = class
- private
- Value: Byte;
- public
- procedure SetValue(newValue: Byte);
- function GetValue: Byte;
- end;
- TMyObjects = array of TMyClass;
- //
- var
- Form1: TForm1;
- Objects: TMyObjects;
- ObjNum: Byte = 15;
-
- implementation
-
- {$R *.dfm}
- procedure TMyClass.SetValue(newValue: Byte);
- begin
- Value := newValue;
- end;
- //
- function TMyClass.GetValue: Byte;
- begin
- Result := Value;
- end;
- //
- procedure TForm1.Button1Click(Sender: TObject);
- var
- i: Byte;
- begin
- SetLength(Objects, ObjNum);
- for i:=1 to ObjNum do
- begin
-
- Objects[i].SetValue(i);
- end;
- end;
-
- end.
-
 |
Вопрос задал: Muratov Radik (статус: Посетитель)
Вопрос отправлен: 12 октября 2010, 11:33
Состояние вопроса: открыт, ответов: 2.
|
Ответ #1. Отвечает эксперт: Тов. Женька
Здравствуйте, Muratov Radik!
Думаю, что нужно создавать экземпляр Objects, а не Objects[i] и уничтожать именно его. Сообщение выскакивает, потому что Objects не создан, а происходит попытка обратиться к его элементу, которого, соответственно, не существует.
Создавать и удалять Objects нужно за пределами цикла.
 |
Ответ отправил: Тов. Женька (статус: 3-ий класс)
Время отправки: 12 октября 2010, 11:39
|
Ответ #2. Отвечает эксперт: min@y™
У тебя тут сразу несколько ошибок.
Переделай вот так:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Byte;
begin
SetLength(Objects, ObjNum);
for i:= 0 to ObjNum - 1 do // <--- индекс дин. массивов всегда идёт с нуля
begin
Objects[i]:= TMyClass.Create; // <--- правильный возов конструктора
Objects[i].SetValue(i + 1);
end;
end;
 |
Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 12 октября 2010, 11:42
Оценка за ответ: 5
Комментарий к оценке: Спасибо! Работает
|
Мини-форум вопроса
Всего сообщений: 17; последнее сообщение — 12 октября 2010, 15:16; участников в обсуждении: 3.
|
min@y™ (статус: Доктор наук), 12 октября 2010, 11:44 [#1]:
А вообще, для хранения списка объектов лучше использовать не дин. массивы, а классы типа TList или TObjectList.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Muratov Radik (статус: Посетитель), 12 октября 2010, 11:44 [#2]:
Objects.Create;
SetLength(Objects, ObjNum);
for i:=0 to ObjNum-1 do
begin
// Objects[i].Create; // тут вылетает Access violation !!!
Objects[i].SetValue(i);
end;
выдает "Record, Object or class type required"
|
|
Muratov Radik (статус: Посетитель), 12 октября 2010, 11:49 [#3]:
min@y™: а почему дин.массивы не использовать?
|
|
min@y™ (статус: Доктор наук), 12 октября 2010, 11:50 [#4]:
Objects.Create; // <--- Это что за порнография?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
min@y™ (статус: Доктор наук), 12 октября 2010, 11:51 [#5]:
Цитата (Muratov Radik):
а почему дин.массивы не использовать?
Потому что работать с классами-списками намного удобнее, быстрее и вероятность ошибок меньше. Мог8у пример набросать.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Muratov Radik (статус: Посетитель), 12 октября 2010, 11:56 [#6]:
min@y™:
был бы очень благодарен. И еще по поводу примера выше, а как удалить эти элементы после использования? Objects[i].Destroy не работает
|
|
min@y™ (статус: Доктор наук), 12 октября 2010, 11:59 [#7]:
Вот, набросал на коленке:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
Contnrs { <--- там TobjectList } ;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
Objects: TObjectList; // <--- список
public
{ Public declarations }
end;
TMyClass = class
private
FValue: Byte;
procedure SetValue(newValue: Byte);
function GetValue: Byte;
public
property Value: Byte read GetValue write SetValue;
end;
var
Form1: TForm1;
ObjNum: Byte = 15;
implementation
{$R *.dfm}
procedure TMyClass.SetValue(newValue: Byte);
begin
FValue := newValue;
// другие действия
end;
function TMyClass.GetValue: Byte;
begin
Result := FValue;
// другие действия
end;
//
procedure TForm1.Button1Click(Sender: TObject);
var
i: Byte;
Obj: TMyObject;
begin
if not Assigned(Objects)
then Objects:= TObjectList.Create(True)
else Objects.Clear();
for i:= 0 to ObjNum - 1 do
begin
Obj:= TMyObject.Create();
Obj.Value:= i + 1;
Objects.Add(Obj);
end;
end;
{ Доступ к объектам в списке:
TMyObject(Objects[Index]).Value:= ...;
}
end.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
min@y™ (статус: Доктор наук), 12 октября 2010, 12:29 [#8]:
Цитата (Muratov Radik):
И еще по поводу примера выше, а как удалить эти элементы после использования? Objects[i].Destroy не работает
В случае с дин. массивом - так:
for Index:= 0 to Length(Objects) - 1 do
if Assigned(Objects[Index])
then Objects[Index].Free();
или так:
for Index:= 0 to Length(Objects) - 1 do
FreeAndNil(Objects[Index]);
В случае с TObjectList (при Objects.OwnsObjects = True) - так:
Objects.Clear();
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
min@y™ (статус: Доктор наук), 12 октября 2010, 13:26 [#10]:
Цитата (Muratov Radik):
большое спасибо!
Что, помогло? Какой вариант выбрал?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Muratov Radik (статус: Посетитель), 12 октября 2010, 13:27 [#11]:
min@y™:
Еще вопрос по поводу "property".
Если не ошибаюсь, это чисто борландовская фича. Ее ввели для vcl-компонентов. Целесообразно ее использовать для простых, невизуальных, классов? Если н/р захочешь использовать этот модуль(класс) в проекте MSVC++, то работать не будет?
Повторюсь, я могу ошибаться, но что-то подобное слышал
|
|
min@y™ (статус: Доктор наук), 12 октября 2010, 13:58 [#13]:
Цитата (Muratov Radik):
Целесообразно ее использовать для простых, невизуальных, классов?
Свойства (property) бывают разные с разной степенью допуска, вычислимые, по умолчанию, события и ещё вагон и маленькая тележка. Все они направлены на удобство управления объектом снаружи, а если это компонент - для визуальной настройке во время проектирования с помощью Object Inspector. Вот тебе маленький пример:
type
TMyObj = class
private
FValue: Integer;
FModified: Boolean;
FOnModify: TNotifyEvent;
procedure SetValue(const ANew: Integer);
public
property Value: Integer read FValue write SetValue; // Свойство - хранимое целое
property Modified: Boolean read FModified write FModified; // Свойство-флаг модифицированности хранимого целого
property OnModify: TNotifyEvent read FOnModify write FOnModify; // Свойство-событие изменения хранимого целого
end;
implementation
procedure SetValue(const ANew: Integer);
begin
// Модификация свойства Value
if ANew <> FValue
then begin
FValue:= ANew; // Присвоение нового значения
FModified:= True; // Установка флага модифицированности
// Вызов события
if Assigned(FOnModify)
then FOnModify(Self);
end;
end;
Здесь при простом присвоении свойству объекта нового значения, например Obj.Value:= 1;, меняется и его другого его свойства и ещё вызывается обработчик события.
Цитата (Muratov Radik):
Если н/р захочешь использовать этот модуль(класс) в проекте MSVC++, то работать не будет?
Интересно, а как можно паскалевский модуль прицепить к проекту на MSVC++? К билдеру можно, там та же VCL (вся написана на паскале) + паскалевский компилятор.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Вадим К (статус: Академик), 12 октября 2010, 14:45 [#14]:
Паскалевсктй модуль так просто к MSVC++ не прицепишь. Но если в виде dll - то никто не мешает.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
min@y™ (статус: Доктор наук), 12 октября 2010, 14:57 [#15]:
Цитата (Вадим К):
Паскалевсктй модуль так просто к MSVC++ не прицепишь. Но если в виде dll - то никто не мешает.
Ну естественно... Модуль (исходник или dcu) и DLL (исполнимый файл) - это "2 большие разницы", как говорят у вас в Одессе.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
min@y™ (статус: Доктор наук), 12 октября 2010, 15:16 [#17]:
Цитата (Muratov Radik):
Имел ввиду билдер
К билдеру - можно.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|