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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 12.02.2010, 16:29   #1
Unconnected
Пользователь
 
Регистрация: 23.06.2008
Сообщений: 55
По умолчанию Вопрос про ООП

Привет всем.

Пишу программу, в отдельном модуле описал свой класс. Код такой:
Код:
unit Unit2;

interface
uses windows,sysutils,extctrls,unit1;

var names:array[1..kolel] of string=('lineroad.jpg');

type line_road = class
  private
    x,y:byte;
  public
    var img:TImage;
    constructor create;
    Procedure move(x,y:byte);
    Procedure draw(var img:TImage;name:string);
end;

implementation

Constructor line_road.create;
begin
  img:=TImage.Create(nil); //<=======
end;

Procedure line_road.move(x,y:byte);
begin
  img.Left:=x;
  img.Top:=y;
end;

Procedure line_road.draw(var img:TImage;name:string);
begin
  img.Picture.LoadFromFile(folder+'images\'+name);
end;

end.
В главном модуле в обработчике кнопки код такой:
Код:
var i,y:integer;
begin
  folder:=extractfilepath(application.exename);
  y:=3;
  for i:=1 to kolel do begin
    constr[i].Create;
    constr[i].move(sscrollbox1.Left+3,sscrollbox1.Top+3+y);
    constr[i].draw(constr[i].img,names[i]);
    inc(y,constr[i].img.Height+4);
  end;
Вылетает Acsess Violation на указанной строке. Причём, если сделать переменную img локальной для конструктора, то всё нормально.. Но мне надо сделать её именно переменной класса.
Unconnected вне форума Ответить с цитированием
Старый 12.02.2010, 16:35   #2
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

1. img должно быть в секции private или protected и без var. Просто правила хорошего тона.
2. У TImage не должен быть родителем никто, иначе у него в паспорте напротив отчества прочерк стоять будет. А это не по фэнь-шую. Грубо говоря, он должен рисовать на родителе, а если родителя нет, то и рисоваться ему не на чем (и не перед кем).
Вот он и ругается.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 12.02.2010, 16:35   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Код:
    constr[i]:= line_road.Create;
Именно так и не иначе создаются обьекты.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 12.02.2010, 20:53   #4
Unconnected
Пользователь
 
Регистрация: 23.06.2008
Сообщений: 55
По умолчанию

Код:
1. img должно быть в секции private или protected и без var.
Да-да, я слышал про инкапсуляцию... Но так не получилось сделать, потому что в строке constr[i].draw(constr[i].img,names[i]); обращаюсь к img, поэтому она должна быть public. Возможно, есть решение, только опыта с ООП у меня нет, не знаю.
Код:
Именно так и не иначе создаются обьекты.
Блин, точно... А в FPC, кажется, так, как я написал.

Спасибо за ответы.
Unconnected вне форума Ответить с цитированием
Старый 12.02.2010, 23:57   #5
Unconnected
Пользователь
 
Регистрация: 23.06.2008
Сообщений: 55
По умолчанию

Ну, сделал я указание родителя - img:=TImage.Create(sscrollbox1); - сделал правильное создание, теперь ошибок не вылетает, но и картинка не показывается, в чём проблема?


Код:
procedure TForm1.FormShow(Sender: TObject);
var i,y:integer;
begin
  y:=3;
  for i:=1 to kolel do begin
    constr[i]:=line_road.create;
    constr[i].move(3,3+y);
    constr[i].draw(constr[i].img,names[i]);
    inc(y,constr[i].img.Height+4);
  end;
end;

unit Unit2;

interface
uses windows,sysutils,extctrls,unit1,forms,classes;

var names:array[1..kolel] of string=('lineroad.jpg');

type line_road = class(TForm1)
  private
    x,y:byte;
  public
    img:TImage;
    constructor create;
    Procedure move(x,y:byte);
    Procedure draw(img:TImage;name:string);
end;

implementation

constructor line_road.create;
begin
  img:=TImage.Create(sscrollbox1);
end;

Procedure line_road.move(x,y:byte);
begin
  img.Left:=x;
  img.Top:=y;
end;

Procedure line_road.draw(img:TImage;name:string);
begin
  img.Picture.LoadFromFile(folder+'Images\'+name);
end;

end.

Последний раз редактировалось Unconnected; 13.02.2010 в 00:56.
Unconnected вне форума Ответить с цитированием
Старый 13.02.2010, 02:39   #6
maxionans
Форумчанин
 
Аватар для maxionans
 
Регистрация: 02.01.2010
Сообщений: 254
По умолчанию

Как минимум имеются две ошибки:

1. После создания TImage нужно указать его ширину и высоту, а так же не забыть сделать его видимым.

2. В line_road.draw убрать из параметров Img : TImage.
maxionans вне форума Ответить с цитированием
Старый 13.02.2010, 11:22   #7
Unconnected
Пользователь
 
Регистрация: 23.06.2008
Сообщений: 55
По умолчанию

Ага, поправил, только ширину и высоту указывать не обязательно - TImage сам адаптируется под загруженное в него изображение. Получилось вывести на форму:

Код:
constructor line_road.create;
begin
  img:=TImage.Create(self);
  img.parent:=form1;
  img.visible:=true;
  img.Show;
end;
Но, что интересно, если написать просто img:=TImage.Create(form1);, то ничего не выводится! Всем спасибо, +++.

Ещё вопрос: вот допустим хочу я сделать конструктор с входным параметром, чтобы img создавалось на компоненте, который был передан в этом параметре.

Код:
constructor line_road.create(sender:TObject);
begin
  img:=TImage.Create(self);
  img.parent:=(sender as TComponent);
  img.visible:=true;
  img.Show;
end;
Мне кажется, как-то так надо? Но это не компилируется.

Последний раз редактировалось Stilet; 15.02.2010 в 16:38.
Unconnected вне форума Ответить с цитированием
Старый 13.02.2010, 12:23   #8
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,528
По умолчанию

Код:
//// TImage.Create(AOwner: TComponent);
 img:=TImage.Create(self);
не работает так как твой класс(self) не является потомком(наследником) класса Tcomponent
можно так
Код:
 img:=TImage.Create(sender);
в этом случае при удалении объекта sender будет удален и твой Image
или
Код:
img:=TImage.Create(nil);
а здесь удаление img полностью зависит от тебя (твоего класса)
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 13.02.2010 в 12:25.
evg_m вне форума Ответить с цитированием
Старый 13.02.2010, 12:30   #9
Unconnected
Пользователь
 
Регистрация: 23.06.2008
Сообщений: 55
По умолчанию

А можно подробней? Не совсем понял:

Цитата:
можно так
Код:


img:=TImage.Create(sender);
А Sender какого типа здесь будет? И как передавать, constr[i]:=line_road.create(scrollbox1); ?
Unconnected вне форума Ответить с цитированием
Старый 13.02.2010, 15:10   #10
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
[CODE]
или
Код:
img:=TImage.Create(nil);
а здесь удаление img полностью зависит от тебя (твоего класса)
Это очень плохая идея. В лучшем случае это будет AV. В худшем трудноотлавливаемая утечка памяти. Тем более, что ТС работает с массивом объектов.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по ООП rocky7 Общие вопросы C/C++ 5 21.08.2009 11:34
Вопрос по программированию в C++(ООП) Katya Melody Помощь студентам 2 24.04.2009 01:08
Вопросик про ООП!!! R@mec Общие вопросы C/C++ 2 22.08.2008 13:38
Вопрос наверное про функции, а так точно даже не знаю про что. (Вопрос начинющего #6) Albert2008 Общие вопросы Delphi 4 21.08.2008 15:33
У меня вопрос про базы данных,а точнее про таблицы!!! Alexij Общие вопросы Delphi 1 13.04.2008 23:24