Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Первые шаги в создании интерфейсов


Bizon's ©   (2004-05-31 20:43:00) 

Привет всем!!!
Объясните кто может (желательно подробнейи с кодом)
 Так вот, есть следующий код
 IMy = interface
   ['{A5C0D7CC-3EC4-4090-A0F8-3D03271877EA}']
   function GetValue1: Integer;
 end;

 TMy = class(TComponent, IMy)
   function GetValue1: Integer;
 end;

 function TMy.GetValue1: Integer;
 begin
   Result := 0;
 end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
 c1, c2: TMy;
 i: Integer;
begin
 c1:=TMy.Create(Self);
 i:=(c1 as IMy).GetValue1;
 ShowMessage(IntToStr(i));
 c1.Destroy;

 c2:=TMy.Create(Self);
 i:=(c2 as IMy).GetValue1;
 ShowMessage(IntToStr(i));
  c2.Destroy;
end;


 И вот не последнем дестое выбивает аксес виолейшен.
 Объясните в чем  проблема. Или киньте ссылки URL где можно почитать.


  (2004-06-17 07:12:00) [1]

Удалено модератором


malkolinge   (2004-06-16 19:43:00) [2]

Просто запомни правило. Если у объекта запршен интерфейс, то вызывать деструктор нельзя. Причина - автоматический подсчет ссылок. Кстати к TComponent это не относиться


default   (2004-06-08 22:51:00) [3]

а кто спорит?


Cobalt   (2004-06-08 08:38:00) [4]

Если c1, c2: IMy;
то при присвоении Nil будет освобождаться эта переменная и (смею утверждать) будет вызван метод _Release.


default   (2004-06-05 18:52:00) [5]

Bizon's ©   (05.06.04 11:10) [12]
писать надо так как в [1]


Bizon's   (2004-06-05 11:10:00) [6]

В таком случае освобождается ли память после c1 и c2 или нет (_Release вызывается только один раз)?


APXi   (2004-06-04 22:06:00) [7]

...
ShowMessage(IntToStr(i));
//c1.Destroy;
c1 := nil;

...
ShowMessage(IntToStr(i));
//c2.Destroy;
c2 := nil;


Cobalt   (2004-06-04 15:55:00) [8]

Говорят, что у Анатолия Подгорецкого на сайте есть хорошая книга по 5-ой Дельфи, там, типа, хорошо описано про интерфейсы. Хотя сам ещё не читал, но мне рекомендуют.


Bizon's   (2004-06-03 21:24:00) [9]

Что неужели никто не знает?

Например, когда привести TComponent к интерфейсу IInterface и вызвать функцию с интерфейса, то все работает отлично.
Так что же делать?


Bizon's   (2004-06-02 11:17:00) [10]

С этим я согласен, сам на днях проверал.

Но как можна избежать AV? Может нужно переписать _AddRef и _Release чтобы правильно ссылки считало? И как это правильно сделать?


default   (2004-06-02 01:14:00) [11]

ещё такой момент
procedure TForm1.Button1Click(Sender: TObject);
var
c1, c2: TMy;
i: Integer;
begin
c1:=TMy.Create(Self);
i:=(c1 as IMy).GetValue1;
ShowMessage(IntToStr(i));
c1.Destroy;

c2:=TMy.Create(Self);
i:=(c2 as IMy).GetValue1;
ShowMessage(IntToStr(i));
//c2.Destroy;

end;
такой код работать будет поск-ку первый об-т ты унич-ешь сам, второй же уничт-ся после выхода из проц-ры кодом комп-ра(из-за интер-ой пере-ой, кстати в этом коде она только одна созд-ся комп-ом и "связана" в конце уже со вторыи об-ом)

procedure TForm1.Button1Click(Sender: TObject);
var
c1, c2: TMy;
i: Integer;
begin
c1:=TMy.Create(Self);
i:=(c1 as IMy).GetValue1;
ShowMessage(IntToStr(i));
//c1.Destroy;

c2:=TMy.Create(Self);
i:=(c2 as IMy).GetValue1;
ShowMessage(IntToStr(i));
c2.Destroy;

end;
такой раб-ать не будет
первый об-т удал-ся компил-ом как мусор, интер-ая же пер-ая "связана" уже со вторым об-ом поэтому удал-ие второго об-та будет "двойным" что вызовет AV
думаю всё стало понятно


default   (2004-06-02 00:58:00) [12]

вот так будет работать
procedure TForm1.Button1Click(Sender: TObject);
var
c1, c2: TMy;
i: Integer;
begin
c1:=TMy.Create(Self);
i:=(c1 as IMy).GetValue1;
ShowMessage(IntToStr(i));

c2:=TMy.Create(Self);
i:=(c2 as IMy).GetValue1;
ShowMessage(IntToStr(i));
end;
как я понял при привед-ии класса к интер-су созд-ся интер-ая пер-ая
ты убиваешь об-т, а при выходе из проц-ры код компил-ра пыт-ся ещё раз убить об-т и возн-ет AV(поскольку число ссылок на об-т обнуляется - всё из-за созд-ия интер-ой пер-ой)
поэтому убрав дестр-ры всё и зараб-ло
лучше делай так как в [1]+[3]


Bizon's   (2004-06-02 00:27:00) [13]

Да ну всеже объясните в чем проблема? В чем ошибка?

Нужно расширить какой то класс на несколько функций, а потом
привести именно к интерфейсуи вызвать функцию.


Cobalt   (2004-06-01 21:39:00) [14]

А в 4-ой Дельфе вообще ругается на
i:=(c1 as IMy).GetValue1;
[Error] Unit1.pas(47): Operator not applicable to this operand type
А после этого
i:=c1.GetValue1;- Всё ок.

А вот в 7-ой - всё тихо, как в могиле ;-)


default   (2004-05-31 23:26:00) [15]

только вот это оставь
TMy = class(TComponent, IMy)
  function GetValue1: Integer;
end;
а не это...
TMy = class(TInterfacedObject, IMy)
function GetValue1: Integer;
end;


default   (2004-05-31 23:04:00) [16]

да лучше с теории начинать, типа нафиг там какие-то интерфейсы придумали...


VMcL   (2004-05-31 22:58:00) [17]

>> Bizon's ©  (31.05.04 20:43)

IMy = interface
 ['{A5C0D7CC-3EC4-4090-A0F8-3D03271877EA}']
 function GetValue1: Integer;
end;

TMy = class( TInterfacedObject, IMy)
 function GetValue1: Integer;
end;

function TMy.GetValue1: Integer;
begin
 Result := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
c1, c2: IMy;
i: Integer;
begin
c1:=TMy.Create(Self);
i:=c1 .GetValue1;
ShowMessage(IntToStr(i));
//c1.Destroy;

c2:=TMy.Create(Self);
i:= c2.GetValue1;
ShowMessage(IntToStr(i));
//c2.Destroy;
end;

?


Наверх

Титульная страница Поиск, карта сайта Написать письмо