Форум: "Начинающим";
Текущий архив: 2010.12.12;
Скачать: [xml.tar.bz2];
ВнизПростой вопрос по классам Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.004 c