![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Первые шаги в создании интерфейсов
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;
?