Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 649

/ вопрос открыт /

Приветствую, уважаемые эксперты!

Подскажите пжлста в чем ошибка? Вылетает в обозначенной строке

Приложение:
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, StdCtrls;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11. Button1: TButton;
  12. Memo1: TMemo;
  13. procedure Button1Click(Sender: TObject);
  14. private
  15. { Private declarations }
  16. public
  17. { Public declarations }
  18. end;
  19. //
  20. TMyClass = class
  21. private
  22. Value: Byte;
  23. public
  24. procedure SetValue(newValue: Byte);
  25. function GetValue: Byte;
  26. end;
  27. TMyObjects = array of TMyClass;
  28. //
  29. var
  30. Form1: TForm1;
  31. Objects: TMyObjects;
  32. ObjNum: Byte = 15;
  33.  
  34. implementation
  35.  
  36. {$R *.dfm}
  37. procedure TMyClass.SetValue(newValue: Byte);
  38. begin
  39. Value := newValue;
  40. end;
  41. //
  42. function TMyClass.GetValue: Byte;
  43. begin
  44. Result := Value;
  45. end;
  46. //
  47. procedure TForm1.Button1Click(Sender: TObject);
  48. var
  49. i: Byte;
  50. begin
  51. SetLength(Objects, ObjNum);
  52. for i:=1 to ObjNum do
  53. begin
  54.  
  55. Objects[i].SetValue(i);
  56. end;
  57. end;
  58.  
  59. end.
  60.  


Muratov Radik Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: 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™

min@y™ (статус: Доктор наук), 12 октября 2010, 11:44 [#1]:

А вообще, для хранения списка объектов лучше использовать не дин. массивы, а классы типа TList или TObjectList.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Muratov Radik

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

Muratov Radik (статус: Посетитель), 12 октября 2010, 11:49 [#3]:

min@y™: а почему дин.массивы не использовать?
min@y™

min@y™ (статус: Доктор наук), 12 октября 2010, 11:50 [#4]:

Objects.Create; // <--- Это что за порнография?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
min@y™

min@y™ (статус: Доктор наук), 12 октября 2010, 11:51 [#5]:

Цитата (Muratov Radik):

а почему дин.массивы не использовать?

Потому что работать с классами-списками намного удобнее, быстрее и вероятность ошибок меньше. Мог8у пример набросать.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Muratov Radik

Muratov Radik (статус: Посетитель), 12 октября 2010, 11:56 [#6]:

min@y™:
был бы очень благодарен. И еще по поводу примера выше, а как удалить эти элементы после использования? Objects[i].Destroy не работает
min@y™

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™

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. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Muratov Radik

Muratov Radik (статус: Посетитель), 12 октября 2010, 13:16 [#9]:

min@y™:
большое спасибо!
min@y™

min@y™ (статус: Доктор наук), 12 октября 2010, 13:26 [#10]:

Цитата (Muratov Radik):

большое спасибо!

Что, помогло? Какой вариант выбрал?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Muratov Radik

Muratov Radik (статус: Посетитель), 12 октября 2010, 13:27 [#11]:

min@y™:
Еще вопрос по поводу "property".
Если не ошибаюсь, это чисто борландовская фича. Ее ввели для vcl-компонентов. Целесообразно ее использовать для простых, невизуальных, классов? Если н/р захочешь использовать этот модуль(класс) в проекте MSVC++, то работать не будет?
Повторюсь, я могу ошибаться, но что-то подобное слышал
Muratov Radik

Muratov Radik (статус: Посетитель), 12 октября 2010, 13:38 [#12]:

Блин. Я что-то не то написал, сорри :) Я просто еще параллельно в билдере пишу, запутался :)
Но по поводу "property" все равно интересно.
min@y™

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™

min@y™ (статус: Доктор наук), 12 октября 2010, 14:57 [#15]:

Цитата (Вадим К):

Паскалевсктй модуль так просто к MSVC++ не прицепишь. Но если в виде dll - то никто не мешает.

Ну естественно... Модуль (исходник или dcu) и DLL (исполнимый файл) - это "2 большие разницы", как говорят у вас в Одессе. :)
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Muratov Radik

Muratov Radik (статус: Посетитель), 12 октября 2010, 15:11 [#16]:

Да. Я оговорился. Извинился уже тут
Muratov Radik (статус: Посетитель), сегодня, 13:38:

Блин. Я что-то не то написал, сорри :) Я просто еще параллельно в билдере пишу, запутался :)
Но по поводу "property" все равно интересно.

Имел ввиду билдер
min@y™

min@y™ (статус: Доктор наук), 12 октября 2010, 15:16 [#17]:

Цитата (Muratov Radik):

Имел ввиду билдер

К билдеру - можно.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:48
Выполнено за 0.04 сек.