Compiler pointer yönetim işini bizim yerimize yapıyorsa;
System.Rtti.pas 1075 nolu satırda ki
TRawVirtualClass sınıfı ne amaçla yazılmış olabilir acaba diye düşünürken...
He ne kadar sınıfın tepesinde ki açıklama notunu okusam da tam olarak idrak edemedim.
Kod: Tümünü seç
/// Provides a basis for dynamically creating instances that implement
/// interfaces. The support here is extremely raw. You create an instance
/// of a virtual class by handing it a vtable. The vtable is a specialized
/// type defined here. The vtable will be populated with slots that point
/// to small thunks that dispatch to user code.<p></p>
///
/// The basic usage model is to construct a virtual class with a vtable,
/// and a list of GUIDs of interfaces that the vtable matches. Thus if
/// you have an interface declared to inherit a line of several parents,
/// the single vtable will represent each of the parent interfaces.<p></p>
///
/// The <code>TRawVirtualClass</code> implements <code>QueryInterface</code>,
/// <code>AddRef</code> and <code>Release</code> for the interface, so
/// that you can query an instance and get back a Delphi interface that can
/// be used as if it were any Delphi interface.<p></p>
///
/// Future improvements: support adding vtables to an existing instance.
Ama sanırım şuan yazarken jeton düştü sanırım
Provides a basis for dynamically creating instances that implement interfaces.
Normalde bir interface'i implement sınıfı oluştururken şöyle bir yöntem izliyoruz.
Kod: Tümünü seç
ITest = interface(IInterface)
procedure Invoke();
end;
TTestImp1 = class(TInterfacedObject,ITest)
procedure Invoke();
end;
TTestImp2 = class(TInterfacedObject,ITest)
procedure Invoke();
end;
{ TTestImp1 }
procedure TTestImp1.Invoke;
begin
ShowMessage('Test 1');
end;
{ TTestImp2 }
procedure TTestImp2.Invoke;
begin
ShowMessage('Test 2');
end;
Kullanım :
Kod: Tümünü seç
procedure TForm2.Button1Click(Sender: TObject);
var
ATest : ITest;
begin
ATest := TTestImp1.Create;
ATest.Invoke;
ATest := TTestImp2.Create;
ATest.Invoke;
end;
TRawVirtualClass sınıfının tepesinde ki açıklamada ki ilk cümle sanırım kilit nokta.
"Provides a basis for dynamically creating instances that implement interfaces."
Yani interface'i implement eden sınıfların oluşturulma(Create) işini biz üstlenmiyoruz.
Kod: Tümünü seç
uses System.Rtti;
procedure TForm2.Button2Click(Sender: TObject);
var
ATest : ITest;
Adress : Pointer;
Imp1 : TTestImp1;
Imp2 : TTestImp2;
begin
Adress := @ATest;
Imp1 := TTestImp1(TRawVirtualClass.GetInstanceFromInterface(Adress));
Imp1.Invoke;
Imp2 := TTestImp2(TRawVirtualClass.GetInstanceFromInterface(Adress));
Imp2.Invoke;
end;
Bu kod bloğunda TTestImp1.Create şeklinde bir constructor çağırımı yaptık mı ? yapmadık.
Yani bizim yerimize ITest interface'i implement eden TTestImp1 ve TTestImp2 sınıflarının instance'ları dinamik olarak oluşturuldu.
Nesne oluşturma kontrolü bizden çıkıyor bu durumda (
inversion of control)
Tuğrul Bey bu konuda ki fikirlerinizi paylaşırsanız sevinirim.
Hem yanlış anlayıp idrak ettiğimiz birşey varsa düzeltme imkanı buluruz.