Hello guys
Hello guys,
1 - Is there a way to discover if an abstract method has been overrided by a derivated class?
2 - Is there a way to discover if a class is a root class or it inherits another one?
All these questions are without RTTI :D
Thanks in advance :D
1 - Is there a way to discover if an abstract method has been overrided by a derivated class?
2 - Is there a way to discover if a class is a root class or it inherits another one?
All these questions are without RTTI :D
Thanks in advance :D
/sub
ReplyDelete/sub
ReplyDeleteYes and yes
ReplyDeleteYes, inspect the pointers in the VMT
ReplyDelete1. Call the method and catch any EAbstractError
ReplyDelete2. If the class is TObject, it's the root class
I haven't tested this for abstract methods - but should work?
ReplyDeleteunit DetectOverride;
interface
type
TRootClass = class
private
FHasImport: boolean;
FReference: T;
function GetReference: T;
procedure SetReference(const Value: T);
protected
procedure ImportByRTTI; virtual;
property HasImport: boolean read FHasImport write FHasImport;
property HasExport: boolean read FHasImport write FHasImport;
public
constructor Create; virtual;
procedure ImportReference; virtual;
procedure ExportReference; virtual;
property Reference:T read GetReference write SetReference;
end;
TDerivedClass = class(TRootClass)
public
procedure ImportReference; override;
end;
implementation
{ TRootClass }
constructor TRootClass.Create;
var
vm: procedure of object;
begin
Inherited;
vm := Self.ImportReference;
HasImport := TMethod(vm).Code <> @TRootClass.ImportReference;
vm := Self.ExportReference;
HasExport := TMethod(vm).Code <> @TRootClass.ExportReference;
end;
procedure TRootClass.ExportReference;
begin
// Manually copy fields internal properties to reference
end;
function TRootClass.GetReference: T;
begin
if HasExport
then ExportReference;
Result := FReference;
end;
procedure TRootClass.ImportByRTTI;
begin
// Do RTTI magic
end;
procedure TRootClass.ImportReference;
begin
// Manually copy fields from Reference to internal properties
end;
procedure TRootClass.SetReference(const Value: T);
begin
FReference := Value;
if HasImport
then ImportReference
else ImportByRTTI;
end;
{ TDerivedClass }
procedure TDerivedClass.ImportReference;
begin
// In this class, HasImport will be True after create
end;
end.
The above was inspired by Stefan Glienke
ReplyDeleteLars Fosdal I really fail to see how this is related to the question - and also what is up with you and generics? :)
ReplyDeleteStefan Glienke Old sample code. It uses VMT inspection to see if a method has been overridden.
ReplyDelete