Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.25;
Скачать: [xml.tar.bz2];




Вниз

Работа с классами в Delphi 


dimmu   (2002-03-06 10:06) [0]

Добрый день, Мастера! У меня довольно банальный вопрос по классированию в Delphi, а именно по работе с представителями класса.
Вообще говоря, этот материал я намного лучше помню по C++, а классирование в Turbo Pascal"е прошло мимо меня :-)
Так вот, если не сложно - в двух словах: замечания по нижележащему фрагменту (пример объявления класса, плюс конструктор и функция которая не видит представителя класса, передоваемого по ссылке) и (если Вас не затруднит – какие-то рассуждения по вопросу в целом.


PCellLetter=^TCellLetter;

TCellLetter = class(TObject)
Letter:char;
CellUp:PCellLetter;
CellDown:PCellLetter;
CellRight:PCellLetter;
CellLeft:PCellLetter;
....
constructor Create; overload;
destructor Destroy;
....
procedure SetCoord(Init_x,Init_y:integer);
protected
x,y:integer;
end;
....



constructor TCellLetter.Create;
begin
Letter:=char(0);
CellUp:=nil;
CellDown:=nil;
CellRight:=nil;
CellLeft:=nil;
x:=-1;
y:=-1;
end;

procedure TCellLetter.SetCoord(Init_x,Init_y:integer);
begin
if (x<0) or (x>4) or (y<0) or (y>4) then Exit;
x:=Init_x;
y:=Init_y;
end;

//Вот здесь-то и нужны пояснения:
//либо я неправильно создаю объект, либо нельзя таким
//образом присваивать указатели. Насколько я
//помню из C++, там надо было перегружать оператор
//присваивания, создавать второй экземпляр и копировать поля.
//посоветуйте, что делать здесь - при вызове функции
//SetCoord происходит ошибка в месте где присваиваются
//x и y.
var PCell:PCellLetter;
...
PCell:=Pointer(TCellLetter.Create(Letter,Move));
if (Head=nil) then
begin
Head:=PCell;
Head.SetCoord(x,y);
Result:=Head;
Exit;
end;



Посоветуйте - где найти какой-нибудь классический пример на работу с классами в Delphi - с динамическим выделением памяти, передачей педставителя класса в функцию, работой со ссылками и т.д.



DieHard   (2002-03-06 10:15) [1]

В Delphi объекты создаются так:

var
Cell:TCellLetter;
begin
...
Cell:=TCellLetter.Create(Letter,Move);
...

Cell по существу и является указателем, так что никаких дополнительных действий делать не нужно



nebula   (2002-03-06 10:18) [2]

Занесло тебя однако.
PCellLetter = ^... - совсем не нужно.
CellXXX: TCellLetter
CellXXX := TCellLetter.Create
для предварительного описания класса просто пиши
TCellLetter = class;
Перегрузки операторов в Pascal-е нет.
constructor Create; - overeload лишний.
и т.д и т.п. Почитай про Object Pascal. Пожалуйста.



Виктор Щербаков   (2002-03-06 10:22) [3]

Экземпляры классов в Object Pascal создаются динамически. По-этому переменные классового типа являются указателями. В стеке можно создавать только объекты (эта модель оставлена для совместимости со старыми вепсиями Object Pascal). Смотри в хэлпе: object types. Но Borland не рекоммендует этим пользоваться.



dimmu   (2002-03-08 17:57) [4]

Ага, а как с передачей представителя класса в функцию/процедуру? Здесь есть какие-нибудь хитрости?



drpass   (2002-03-08 19:28) [5]

Никаких хитростей. Передается так же ссылка на экземпляр.
Кстати, при создании нового экземпляра Delphi автоматически устанавливает нулевые значения для всех членов данных, так что нет необходимости инициализировать их в конструкторе.
То же самое касается и наследования от TObject - явно или неявно, хочешь ты этого или нет, любой создаваемый класс будет его потомком.

Так должно работать
var Cell:TCellLetter;
...
Cell:=TCellLetter.Create(Letter,Move);
if not Assigned(Head) then
begin
Head:=Cell;
Head.SetCoord(x,y);
Result:=Head;
Exit;
end;



dimmu   (2002-03-09 00:10) [6]

Это ясно. Вот еще вопрос: после присваивания

Head:=Cell;

ссылка Cell будет указывать на тот же объект, на который ссылался Head, и если будет вызвано что-то вроде

dispose(Cell);//при выходе из функции память под все
//локальные переменные будет высвобождаться примерно таким
//образом - при автоматическом вызыве деструктора.

то Head будет ссылаться на что-то очень сомнительное (nil в лучшем случае).
Насколько я помню в С++ с этим боролись перегрузкой "="(как я уже писал выше), а как поступают в Delphi?



Dimk   (2002-03-09 00:38) [7]

Head-у присвоится указатель на тот же объект.
Говоря на C++ кусок кода

var
Head, Cell: TCellLetter;
begin
Cell := TCellLetter.Create;
Head := Cell;
end;

выглядит так:

{
TCellLetter * Head, Cell; // в Паскале переменная объектного типа - указатель ( хотя явно это не видно а написано в доке ...)

Cell = new TCellLetter();
Head = Cell;
}



drpass   (2002-03-09 00:45) [8]

Нет, конечно, если ты явно вызовешь внутри функции деструктор экземпляра, например, Cell.Destroy, то объект разрушится.
Однако при выходе из функции высвобождается только память под локальные переменные, а динамические объекты в памяти тут не причем, и ничего с твоим экземпляром не произойдет.




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.25;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.74 MB
Время: 0.033 c
3-80389           Jony                  2002-02-25 11:09  2002.03.25  
Куда деваются ошибки?


3-80388           Sewix                 2002-02-23 09:46  2002.03.25  
в чем лучше писать БД


7-80699           Gravitator            2001-12-22 08:15  2002.03.25  
Загрузочный сектор винта


1-80609           AndrewSM              2002-03-11 10:24  2002.03.25  
Отладка COM+


1-80462           Leonon                2002-03-12 09:32  2002.03.25  
Диалог + TComboEdit и автоматический ModalResult