Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.20;
Скачать: CL | DM;

Вниз

Первые шаги в создании интерфейсов   Найти похожие ветки 

 
Bizon's ©   (2004-05-31 20:43) [0]

Привет всем!!!
Объясните кто может (желательно подробнейи с кодом)
 Так вот, есть следующий код
 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 где можно почитать.


 
VMcL ©   (2004-05-31 22:58) [1]

>>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;

?


 
default ©   (2004-05-31 23:04) [2]

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


 
default ©   (2004-05-31 23:26) [3]

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


 
Cobalt ©   (2004-06-01 21:39) [4]

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

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


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

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

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


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

вот так будет работать
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]


 
default ©   (2004-06-02 01:14) [7]

ещё такой момент
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
думаю всё стало понятно


 
Bizon's ©   (2004-06-02 11:17) [8]

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

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


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

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

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


 
Cobalt ©   (2004-06-04 15:55) [10]

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


 
APXi   (2004-06-04 22:06) [11]

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

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


 
Bizon's ©   (2004-06-05 11:10) [12]

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


 
default ©   (2004-06-05 18:52) [13]

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


 
Cobalt ©   (2004-06-08 08:38) [14]

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


 
default ©   (2004-06-08 22:51) [15]

а кто спорит?


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

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


 
имя   (2004-06-17 07:12) [17]

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



Страницы: 1 вся ветка

Текущий архив: 2005.03.20;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.067 c
14-1109566131
ex080D:07BBh
2005-02-28 07:48
2005.03.20
What the hell is going on?


1-1109944168
bon
2005-03-04 16:49
2005.03.20
Autocad &Delphi


3-1108984897
SeZuka
2005-02-21 14:21
2005.03.20
Использование команды SET (MSSQL) и компонент ADO


1-1109860385
SAI
2005-03-03 17:33
2005.03.20
Memo


3-1108833569
Leonardo
2005-02-19 20:19
2005.03.20
Как получить верный результат используя SUM()