![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Простой вопрос по классам
classclass © (2010-09-21 09:35:00)Здравствуйте
Создаю класс 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;
Anatoly Podgoretsky (2010-09-21 11:18:00) [1]> classclass (21.09.2010 09:58:09) [9]
> Несколько лет не запускал delphi
И за это тоже ухи оторвем :-)
Ega23 (2010-09-21 10:47:00) [2]сделал бы просто открытый массив
Тогда уж как-то так
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;
12 (2010-09-21 10:08:00) [3]сделал бы просто открытый массив
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:06:00) [4]
> 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;
Но за такое бьют очень долго, а потом варят на медленном огне.
classclass (2010-09-21 10:04:00) [5]
> За объявление локальной переменной с именем Result
:)
Не буду так делать, первое что в голову попало - то и написал, создавая данную тему
)
classclass (2010-09-21 10:03:00) [6]
> TForm1.Button1Click - это ПРОЦЕДУРА, а не функция. Поэтому
> в ней нет того Result, который есть в функции.
result - там обычная локальная переменная...
>
> var
> result:Tcls;
Причем тут это сказано то?
> icWasya
спасибо
Со всем рзобрался
Всех благодарю за помощь
Ega23 (2010-09-21 10:01:00) [7]
> Да простой вопрос, ну зачем же так сразу то грубить, ухи
> отрывать :) Я не мальчик далеко уже то.
А, если не мальчик, то присоединяюсь к Подгорецкому. За объявление локальной переменной с именем Result надо не просто ухи отрывать, но и по жёппе бить.
Ega23 (2010-09-21 10:00:00) [8]1. TForm1.Button1Click - это ПРОЦЕДУРА, а не функция. Поэтому в ней нет того Result, который есть в функции.
2. Чтобы работать с экземпляром класса, его необходимо создать (вызвать конструктор).
3. По окончании работы с экземпляром класса его нужно удалить (вызвать деструктор), для того чтобы освободить память и прочие ресурсы.
В общем виде при создании локальных экземпляров какого-либо класса шаблон выглядит так:
var
obj: TMyClass;
begin
obj := TMyClass.Create();
try
/// Работа с obj
finally
obj.Free;
end;
end;
> Да рано тебе еще собственные классы писать
Ничё, пусть учится.
classclass (2010-09-21 09:58:00) [9]:)
При всем уважении к Анатолию, рано или не рано, ну давайте без этого.
Да простой вопрос, ну зачем же так сразу то грубить, ухи отрывать :) Я не мальчик далеко уже то.
Несколько лет не запускал delphi, все со временем забывается.
> И. Павел
Благодарю за помощь
icWasya (2010-09-21 09:52:00) [10]в процедуре 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 то же сделать методом формы.
Затем разберитесь с логикой а там посмотрим.
Anatoly Podgoretsky (2010-09-21 09:49:00) [11]> classclass (21.09.2010 09:41:02) [2]
> отдельный класс создать
Да рано тебе еще собственные классы писать
Anatoly Podgoretsky (2010-09-21 09:48:00) [12]
> result:Tcls;
А за это ухи оторвать.
Anatoly Podgoretsky (2010-09-21 09:47:00) [13]> classclass (21.09.2010 09:35:00) [0]
А массив будет Пушкин создавать?
И. Павел (2010-09-21 09:46:00) [14]Извиняюсь, я ступил.
В функции funct нужно создать объект result:
result := TCls.Create;
И. Павел (2010-09-21 09:44:00) [15]> Указать явно, что возвращаться будет массив не могу, т.к.
> помимо массива будут возвращаться еще значения, пожтому
> и хочу отдельный класс создать, где все это собрать
Объявите новый тип, который будет соответствовать массиву элементов этого класса, и возвращайте его. Или создайте класс, содержащий массив классов, и возвращайте его.
classclass (2010-09-21 09:41:00) [16]Указать явно, что возвращаться будет массив не могу, т.к. помимо массива будут возвращаться еще значения, пожтому и хочу отдельный класс создать, где все это собрать
И. Павел (2010-09-21 09:38:00) [17]А зачем так писать? Скажите функции явно, что тип ее возвращаемого значения - массив.
Это в C++ массив и указатель на первый элемент - почти одно и то же. А насчет pascal я такого утверждения нигде не встречал.