Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.06.2013, 18:49   #1
Tclass
Пользователь
 
Регистрация: 02.06.2013
Сообщений: 11
По умолчанию Композиция классов и объектов в Delphi

Имеются два класса точка и линия. объекты класса точка являются полем данных класса линия. при вызове конструктора точки все замечательно а вот при вызове конструктора лини все ужасно и плохо. Пожалуйста помогите
Классы
Код:
TPoint = class

		constructor Init(initX,initY:integer);
		function GetX:integer;
		function GetY:integer;
		procedure PutX(newX:integer);
		procedure PutY(newY:integer);
		procedure Show;
		procedure Hide;
		procedure Move(newX,newY:integer);
    private
     X:integer;
     Y:integer;
  end;

    TLine=class
    P1:TPoint;
		P2:TPoint;
		constructor Init(initP1,initP2:TPoint);
		procedure PutP1(newP1:TPoint);
		procedure PutP2(newP2:TPoint);
		procedure Show;
		procedure Hide;
		procedure Move(DX,DY:integer);
end;

constructor TPoint.Init(initX,initY:integer);
begin
	X:=initX;
	Y:=initY;
end;

function TPoint.GetX; begin GetX:=X; end;

function TPoint.GetY; begin GetY:=Y; end;

procedure TPoint.PutX(newX:integer); begin X:=newX; end;

procedure TPoint.PutY(newY:integer); begin Y:=newY; end;

procedure TPoint.Show;
begin Form2.PaintBox6.Canvas.Pixels[X,Y]:=ClBlack; end;

procedure TPoint.Hide;
begin Form2.PaintBox6.Canvas.Pen.Color:=clWhite;
form2.PaintBox6.Canvas.Pixels[X, Y]:=Form2.PaintBox6.Canvas.Pen.Color;
Form2.PaintBox6.Canvas.Pen.Color:=clBlack;
end;

procedure TPoint.Move(newX,newY:integer);
begin
	Hide;
	X:=newX;
	Y:=newY;
	Show;
end;

constructor TLine.Init(initP1,initP2:TPoint);
begin
	P1.X:=initP1.GetX;
	P1.Y:=initP1.GetY;
	P2.X:=initP2.GetX;
	P2.Y:=initP2.GetY;
end;

procedure TLine.Show;
begin
  Form2.PaintBox6.Canvas.Moveto(P1.GetX, P1.GetY);
	Form2.PaintBox6.Canvas.LineTo(P2.GetX, P2.GetY);
end;

procedure TLine.Hide;
begin
  Form2.PaintBox6.Canvas.Pen.Color:=clWhite;
  Form2.PaintBox6.Canvas.Moveto(P1.GetX, P1.GetY);
	Form2.PaintBox6.Canvas.LineTo(P2.GetX, P2.GetY);
	Form2.PaintBox6.Canvas.Pen.Color:=clBlack;
end;

procedure TLine.PutP1(newP1:TPoint);
begin
	P1.PutX(newP1.GetX);
	P1.PutY(newP1.GetY);
end;

procedure TLine.PutP2(newP2:TPoint);
begin
	P2.PutX(newP2.GetX);
	P2.PutY(newP2.GetY);
end;

procedure TLine.Move(DX,DY:integer);
begin
	Hide;
	P1.PutX(P1.GetX+DX);
	P1.PutY(P1.GetY+DY);
	P2.PutX(P2.GetX+DX);
	P2.PutY(P2.GetY+DY);
	Show;
end;


вот тут я вызываю
Код:
procedure TForm2.Button7Click(Sender: TObject);
var

	P1,P2:Unit6.TPoint;
	L1:Unit6.TLine;
	switcher,i,j:integer;

begin
switcher:=StrToInt(Form2.Label6.Caption);

P1:=Unit6.TPoint.Init(20,250);
P2:=Unit6.TPoint.Init(100,250);
 if switcher=0 then
  begin
    P1.Show;
    P2.Show;
    L1:=Unit6.TLine.Init(P1,P2);
  end;
  if switcher=1 then
  begin

	L1.Show;
  end;
   switcher:=switcher+1;
  Form2.Label6.Caption:=IntToStr(switcher);
end;
Tclass вне форума Ответить с цитированием
Старый 02.06.2013, 21:41   #2
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Вы плохо усвоили раздел создания и манипуляции с экземплярами классов.
Код:
constructor TLine.Init(initP1,initP2:TPoint);
begin
	P1.X:=initP1.GetX;
	P1.Y:=initP1.GetY;
	P2.X:=initP2.GetX;
	P2.Y:=initP2.GetY;
end;
Этот код присваивает полям Р1 Р2 только что созданного класса линии некие значения. А теперь подумайте, кто создаст сами экземпляры классов для этих полей ?
А ещё подумайте, что в "клиентском" коде, по нажатию кнопки создающего линию - нет вызова деструкторов для промежуточно созданных экземпляров классов точек, они остаются в памяти и "теряются" при окончании процедуры, для процедуры они локальные переменные. Аналогично и экземпляр линии теряется (локальная переменная) и больше никак с ней взаимодействовать нельзя (потеряна ссылка на сам экземпляр), хотя линия и будет отображаться, т.к. отрисовка её на форме не хзависит от существования экземпляра и ссылки на него.

У Вас есть 2 выхода:
Сделать конструктор линии таким , чтобы запоминал себе переданные ему экземпляры точек.
Код:
P1:=initP1;
P2:=initP2;
Тогда им не надо будет вызывать деструктор в клиентском коде.
Либо перед присвоением в эти поля (типа класса точек ) создать их экземпляр, вызвав конструктор (а также написать деструктор для класса линии, в котором их уничтожать, чтобы не терять память, ну и когда линия больше не нужна вызывать её деструктор). Тогда надо в клиентском коде вызывать деструктор и для точек (ведь они используются только для передачи данных в экземпляр класса линии, после создания которой, они больше не нужны и занимают память (а по выходу из процедуры, указатель на них вообще будет потерян).
Также есть и общая проблема - не стоит создавать экземпляры классов в виде локальных переменных, если планируется с ними работа в течение длительного времени, а иначе они существуют только в момент работы кода обработчика кнопки, а после этого будут потеряны ссылки на них (локальные переменные выйдут из области видимости, а они единственные, которые держат ссылку на созданные объекты), и память будет "утекать"
phomm вне форума Ответить с цитированием
Старый 02.06.2013, 21:45   #3
Tclass
Пользователь
 
Регистрация: 02.06.2013
Сообщений: 11
По умолчанию

Цитата:
Сообщение от phomm Посмотреть сообщение
Вы плохо усвоили раздел создания и манипуляции с экземплярами классов.
Код:
constructor TLine.Init(initP1,initP2:TPoint);
begin
	P1.X:=initP1.GetX;
	P1.Y:=initP1.GetY;
	P2.X:=initP2.GetX;
	P2.Y:=initP2.GetY;
end;
Этот код присваивает полям Р1 Р2 только что созданного класса линии некие значения. А теперь подумайте, кто создаст сами экземпляры классов для этих полей ?
А ещё подумайте, что в "клиентском" коде, по нажатию кнопки создающего линию - нет вызова деструкторов для промежуточно созданных экземпляров классов точек, они остаются в памяти и "теряются" при окончании процедуры, для процедуры они локальные переменные. Аналогично и экземпляр линии теряется (локальная переменная) и больше никак с ней взаимодействовать нельзя (потеряна ссылка на сам экземпляр), хотя линия и будет отображаться, т.к. отрисовка её на форме не хзависит от существования экземпляра и ссылки на него.

У Вас есть 2 выхода:
Сделать конструктор линии таким , чтобы запоминал себе переданные ему экземпляры точек.
Код:
P1:=initP1;
P2:=initP2;
Тогда им не надо будет вызывать деструктор в клиентском коде.
Либо перед присвоением в эти поля (типа класса точек ) создать их экземпляр, вызвав конструктор (а также написать деструктор для класса линии, в котором их уничтожать, чтобы не терять память, ну и когда линия больше не нужна вызывать её деструктор). Тогда надо в клиентском коде вызывать деструктор и для точек (ведь они используются только для передачи данных в экземпляр класса линии, после создания которой, они больше не нужны и занимают память (а по выходу из процедуры, указатель на них вообще будет потерян).
Также есть и общая проблема - не стоит создавать экземпляры классов в виде локальных переменных, если планируется с ними работа в течение длительного времени, а иначе они существуют только в момент работы кода обработчика кнопки, а после этого будут потеряны ссылки на них (локальные переменные выйдут из области видимости, а они единственные, которые держат ссылку на созданные объекты), и память будет "утекать"
можно вас попросить подробней рассказать о том как создать в конструкторе, потому что аналогичная проблема возникает когда я вызываю метод Show в классе Tline
Tclass вне форума Ответить с цитированием
Старый 02.06.2013, 21:47   #4
Tclass
Пользователь
 
Регистрация: 02.06.2013
Сообщений: 11
По умолчанию

procedure TLine.Show;
begin
Form2.PaintBox6.Canvas.Moveto(P1.Ge tX, P1.GetY);
Form2.PaintBox6.Canvas.LineTo(P2.Ge tX, P2.GetY);
end;

не могли бы вы подсказать, как здесь можно решить такую проблему?
Tclass вне форума Ответить с цитированием
Старый 02.06.2013, 22:45   #5
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Читать до просветления http://delphikingdom.ru/asp/viewitem.asp?catalogid=1186
Читать мой пост - всё уже расписано и варианты даны.
Вызывая line.Show тут
Код:
if switcher=0 then
  begin
    P1.Show;
    P2.Show;
    L1:=Unit6.TLine.Init(P1,P2);
  end;
  if switcher=1 then
  begin

	L1.Show;
  end;
Вы опять же получаете обращение к несозданному экземпляру (на этот раз уже линии, ведь ветка иф в которой он создавался, при вызове show вообще не проходила), а выше я описал проблему при обращении к несозданным экземплярам точек в конструкторе линии.

И впредь указывайте, что за проблема у Вас, ведь несложно написать , что система сообщает про Access Violation и указывает на строку кода P1.X:=initP1.GetX; или L1.Show;

Последний раз редактировалось phomm; 02.06.2013 в 22:47.
phomm вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Использование классов и объектов Alexander_online C# (си шарп) 0 21.05.2013 15:50
Создание классов и объектов Xronikov Помощь студентам 0 25.11.2012 18:57
Диаграммы классов и объектов Belaya_pantera Помощь студентам 1 12.11.2012 22:01
композиция классов с++ нона Помощь студентам 3 06.05.2012 12:22
Создание классов и использование объектов классов при написании программ в среде C++. Frozen inside Помощь студентам 0 16.04.2009 23:18