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

Вниз

Простой вопрос по классам   Найти похожие ветки 

 
classclass   (2010-09-21 09:35) [0]

Здравствуйте

Создаю класс Tcls, подскажите, что тут неправильно. При закрытии программы появляется ошибка access violation.

В чем именно тут ошибка?



...

Tcls = class
 private
 public

   mass:array [1..100] of string;
 end;

function funct:Tcls;
begin
 result.mass[1]:="test";
end;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
   result:Tcls;
   s:string;
begin
 result:=Tcls.Create;
 Result:=funct;
 s:=result.mass[1];
 showmessage(s);

end;


 
И. Павел ©   (2010-09-21 09:38) [1]

А зачем так писать? Скажите функции явно, что тип ее возвращаемого значения - массив.
Это в C++ массив и указатель на первый элемент - почти одно и то же. А насчет pascal я такого утверждения нигде не встречал.


 
classclass   (2010-09-21 09:41) [2]

Указать явно, что возвращаться будет массив не могу, т.к. помимо массива будут возвращаться еще значения, пожтому и хочу отдельный класс создать, где все это собрать


 
И. Павел ©   (2010-09-21 09:44) [3]

> Указать явно, что возвращаться будет массив не могу, т.к.
> помимо массива будут возвращаться еще значения, пожтому
> и хочу отдельный класс создать, где все это собрать

Объявите новый тип, который будет соответствовать массиву элементов этого класса, и возвращайте его. Или создайте класс, содержащий массив классов, и возвращайте его.


 
И. Павел ©   (2010-09-21 09:46) [4]

Извиняюсь, я ступил.
В функции funct нужно создать объект result:
result := TCls.Create;


 
Anatoly Podgoretsky ©   (2010-09-21 09:47) [5]

> classclass  (21.09.2010 09:35:00)  [0]

А массив будет Пушкин создавать?


 
Anatoly Podgoretsky ©   (2010-09-21 09:48) [6]


>    result:Tcls;

А за это ухи оторвать.


 
Anatoly Podgoretsky ©   (2010-09-21 09:49) [7]

> classclass  (21.09.2010 09:41:02)  [2]

> отдельный класс создать

Да рано тебе еще собственные классы писать


 
icWasya ©   (2010-09-21 09:52) [8]

в процедуре Button1Click result - это локальная переменная
в функции Tcls result - это результат работы функции.
теперь по шагам

1) result:=Tcls.Create;
создаёте экземпляр класса и присваиваете локальной переменной.
2.a) Result:=funct;
вызываете функцию funct;
2.b)
внутри функции
 result.mass[1]:="test";
пытаетесь обратиться к неинициализированному результату result - пишете в в память по неопределённому адресу. Может произойти всё что угодно.
2.c)
 выход из функции funct : она возвращает неопределённый результат
2.d) Result:=funct;
 этот результат присваивается локальной переменной.

то что произошло на шаге 2.b в конечном итоге и приводит к AV.

Что делать:
не давать локальным переменным имена типа Result
Решить для начала логику работы с этим классом : какая процедура создаёт, уничтожает и модифицирует экземплары этого класса.

В простом случае, например можно сделать так:
для начала сменить имя, затем сделать не локальной переменной ButtonClic, а полем формы, и процедуру funct то же сделать методом формы.
Затем разберитесь с логикой а там посмотрим.


 
classclass   (2010-09-21 09:58) [9]

:)
При всем уважении к Анатолию, рано или не рано, ну давайте без этого.
Да простой вопрос, ну зачем же так сразу то грубить, ухи отрывать :) Я не мальчик далеко уже то.
Несколько лет не запускал delphi, все со временем забывается.


> И. Павел

Благодарю за помощь


 
Ega23 ©   (2010-09-21 10:00) [10]

1. TForm1.Button1Click - это ПРОЦЕДУРА, а не функция. Поэтому в ней нет того Result, который есть в функции.
2. Чтобы работать с экземпляром класса, его необходимо создать (вызвать конструктор).
3. По окончании работы с экземпляром класса его нужно удалить (вызвать деструктор), для того чтобы освободить память и прочие ресурсы.

В общем виде при создании локальных экземпляров какого-либо класса шаблон выглядит так:

var
 obj: TMyClass;
begin
 obj := TMyClass.Create();
 try
   ///  Работа с obj
 finally
   obj.Free;
 end;
end;



> Да рано тебе еще собственные классы писать

Ничё, пусть учится.


 
Ega23 ©   (2010-09-21 10:01) [11]


> Да простой вопрос, ну зачем же так сразу то грубить, ухи
> отрывать :) Я не мальчик далеко уже то.


А, если не мальчик, то присоединяюсь к Подгорецкому. За объявление локальной переменной с именем Result надо не просто ухи отрывать, но и по жёппе бить.


 
classclass   (2010-09-21 10:03) [12]


> TForm1.Button1Click - это ПРОЦЕДУРА, а не функция. Поэтому
> в ней нет того Result, который есть в функции.

result - там обычная локальная переменная...

>
> var
>    result:Tcls;

Причем тут это сказано то?
> icWasya

спасибо

Со всем рзобрался
Всех благодарю за помощь


 
classclass   (2010-09-21 10:04) [13]


> За объявление локальной переменной с именем Result

:)
Не буду так делать, первое что в голову попало - то и написал, создавая данную тему
)


 
Ega23 ©   (2010-09-21 10:06) [14]


> result - там обычная локальная переменная...


Вот я и говорю, за такое ногу надо отстреливать.

Понимаешь, есть определённый стиль, общепризнанный.
Да, тебе никто не мешает написать так:

TMyClass = class (TObject)
private
 FName: string;
 FCount: Integer;
public
 property Count: string read FName write FName;
 property Name: Integer read FCount write FCount;
end;


Но за такое бьют очень долго, а потом варят на медленном огне.


 
12 ©   (2010-09-21 10:08) [15]

сделал бы просто открытый массив

type

Tcls = class
private
public
  mass:array of string;
  procedure Add(AE:string);
  procedure ShowAll;
  constructor Create;
  destructor Destroy; override;
end;

 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
   procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 AVar:Tcls;
begin
 AVar:=Tcls.Create;
 AVar.Add("test");
 AVar.Add("test2");
 AVar.ShowAll;
 FreeAndNil(AVar);
end;

{ Tcls }

procedure Tcls.Add(AE: string);
begin
 if Length(mass) > 99 then Exit;
 SetLength(mass, Length(mass)+1);
 mass[Length(mass)-1] := AE;
end;

constructor Tcls.Create;
begin
 inherited;
 // MySuperFld.Create;
 // MySuperFld.owner :=
end;

destructor Tcls.Destroy;
begin
 SetLength(mass,0);
 // FreeAndNil(MySuperFld);
end;

procedure Tcls.ShowAll;
var
 i:Integer;
begin
 for i:=0 to Length(mass)-1 do
   ShowMessage( mass[i] );
end;


 
Ega23 ©   (2010-09-21 10:47) [16]

сделал бы просто открытый массив

Тогда уж как-то так

type

Tcls = class
private
 FStrings: TStringList;
 procedure SetStrings(Value: TStrings);
public
 constructor Create;
 destructor Destroy; override;
 property Strings: TStrings read FStrings write SetStrings;
end;

constructor Tcls.Create;
begin
 inherited;
 FStrings := TStringList.Create;
end;

destructor Tcls.Destroy;
begin
 FStrings.Free;
 inherited;
end;

procedure Tcls.SetStrings(Value: TStrings);
begin
 FStrings.Assign(Value);
end;


 
Anatoly Podgoretsky ©   (2010-09-21 11:18) [17]

> classclass  (21.09.2010 09:58:09)  [9]

> Несколько лет не запускал delphi

И за это тоже ухи оторвем :-)



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

Текущий архив: 2010.12.12;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.008 c
15-1283137842
Ewans
2010-08-30 07:10
2010.12.12
Создание полноценного чата на Flash


8-1208284573
SSSS
2008-04-15 22:36
2010.12.12
Программа на прдобие MP3Splittet


15-1283856091
бумбум
2010-09-07 14:41
2010.12.12
Резервное копирование базы MS SQL 2000


3-1239312888
Кевларвестов Семен
2009-04-10 01:34
2010.12.12
Не удается выполнить хранимую процедуру Firebird.


15-1283372979
Юрий
2010-09-02 00:29
2010.12.12
С днем рождения ! 2 сентября 2010 четверг