| 
| 
 | Вопрос # 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. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |