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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.06.2012, 16:05   #1
postal2
Форумчанин
 
Аватар для postal2
 
Регистрация: 31.10.2008
Сообщений: 215
Стрелка Owner и Parent в собственном компоненте.

Здравствуйте.
Пишу свой компонент, есть несколько вопросов.

Допустим, код
Код:
...

type
  TSomeClass = class(TSomeAnotherClass)
  private
    SomeImage: TImage;
  public
    constructor Create(AOwner: TComponent);
  end;
Так вот, при создании SomeImage в конструкторе какие Owner и Parent правильно выставлять? Делаю и то, и другое как Self (ну то есть TSomeClass является и тем, и другим), но при уничтожении экземпляра класса TSomeClass получаю ошибку Invalid pointer operation. Пока что грешу только на неправильное выставление Owner и Parent.

Собственно вопрос - как правильно?

Чуть больше кода -
Код:
constructor Create(AOwner: TComponent);
begin
  SomeImage := TImage.Create(Self);
  SomeImage.Parent := Self;
  inherite Create(AOwner);
end;

Destructor Free;
begin
  SomeImage.Free;
  inherited Free
end;
Ещё вопрос - при уничтожении формы не вызывается деструктор класса, хотя и Owner - форма.
[Ferox]

Последний раз редактировалось postal2; 20.06.2012 в 16:10.
postal2 вне форума Ответить с цитированием
Старый 20.06.2012, 16:11   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Parent вы не задаете сами.
Owner берете из параметра конструктора.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 20.06.2012, 16:14   #3
postal2
Форумчанин
 
Аватар для postal2
 
Регистрация: 31.10.2008
Сообщений: 215
По умолчанию

То есть Parent остаётся nil, я правильно понимаю?

Стоп стоп стоп.. а если TSomeClass - визуальный компонент, то нужно Parent в любом случае задавать. Иначе Image банально не отображается на нём.

Далее, если я задаю функцию типа AddAnotherImage, которая добавляет ещё одну картинку на мой компонент - кого тогда ставить Owner'ом?
[Ferox]

Последний раз редактировалось postal2; 20.06.2012 в 16:18.
postal2 вне форума Ответить с цитированием
Старый 20.06.2012, 16:20   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

constructor TSomeClass.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  SomeImage:=TImage.Create(Self);
  SomeImage.Parent:=Self;
end;

destructor TSomeClass.Destroy;
begin
  SomeImage.Free;
  inherited Destroy;
end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 20.06.2012, 16:30   #5
postal2
Форумчанин
 
Аватар для postal2
 
Регистрация: 31.10.2008
Сообщений: 215
По умолчанию

С Destroy проходит, а вот на Create жалуется, что
[DCC Error] FileView.pas(42): E2170 Cannot override a non-virtual method

На Free жаловалась так же.
К списку вопросов - чем Free отличается от Destroy?
Если мне не изменяет память, то Free просто проверяет не разрушен ли компонент и только после этого вызывает Destroy.
[Ferox]
postal2 вне форума Ответить с цитированием
Старый 20.06.2012, 16:54   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
С Destroy проходит, а вот на Create жалуется, что
[DCC Error] FileView.pas(42): E2170 Cannot override a non-virtual method
вы не наследуетесь от TComponent чтоль?
Цитата:
К списку вопросов - чем Free отличается от Destroy?
деструктор это destroy, перегружаете его, и только его, free не трогаете.
free делает проверку на nil.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 20.06.2012, 16:59   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Как в TSomeAnotherClass прописан Create? И какой класс он наследует? Скорее всего в его конструкторе не стоит override
Free это деструктор. Вы удаляя вызовите Free, а он уже деструктор вызовет
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 20.06.2012, 17:17   #8
postal2
Форумчанин
 
Аватар для postal2
 
Регистрация: 31.10.2008
Сообщений: 215
По умолчанию

От TScrollBox, который в общем-то TComponent является.

Ну в общем-то я разобрался, спасибо большое за советы, впредь буду переопределять именно Destroy.

p.s. ошибка оказалась в совершенно другой функции, которая отвечала за перераспределение объектов на экране.
[Ferox]
postal2 вне форума Ответить с цитированием
Старый 21.06.2012, 01:54   #9
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
Стоп стоп стоп.. а если TSomeClass - визуальный компонент, то нужно Parent в любом случае задавать. Иначе Image банально не отображается на нём.
Он и будет задан, но не в конструкторе, а позже. Ты просто не трогай Parent, пока он тебе не понадобится (читай: вызовут твой метод Show). А если он тебе нужен, но его нет - так и говори:

Код:
uses
  Consts;

...
  if Parent = nil then
    raise EInvalidOperation.CreateFmt(SParentRequired, [Name]);
...
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 21.06.2012, 09:51   #10
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Со вчерашнего дня думал, стоит ли написать, и всё же решил.

На мой взгляд вызывать SomeImage.Free; не нужно. Ведь задан владелец, в унаследованном деструкторе владелец чистит своих подопечных.

Таким образом, думаю, получается дабл-free, ведь ссылка на подопечного ссылается на память, но вот объект из этой памяти уже почищен, и будет попытка обращения к адресу вмт (методу деструктора в вмт) уничтоженного объекта.

Ошибка может оказаться незамеченной из-за особенности менеджера памяти дельфи, но когда-то будет и крешится с АВ
phomm вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Owner Aleksey1989 Помощь студентам 1 13.10.2010 09:49
parent:: stenl1 PHP 16 26.05.2010 12:29
Ошибка в собственном компоненте для D7 apromix Компоненты Delphi 3 20.01.2010 00:47
У кого какая система хранения на собственном компе данных grenles Свободное общение 31 25.10.2009 06:34
Self, Owner, Sender Arkuz Общие вопросы Delphi 5 26.10.2008 00:00