Reputation: 27276
I'm writing a class with some virtual/abstract procedures which I expect to get overridden. However they might not be overridden as well, which is also fine. The problem is finding out whether one of these procedures was actually overridden or not. If they're not overridden, I shouldn't try to call those procedures, and need to go about something different instead. If I try to call one of them and isn't overridden, I get Abstract Error
.
Is there a way I can detect whether these procedures were overridden or not?
Here's a sample of how they're declared:
type
TMyClass = class(TObject)
protected
procedure VProc; virtual;
procedure VAProc; virtual; abstract;
end;
Upvotes: 2
Views: 877
Reputation: 23036
A method that may or may not be overridden is not an abstract method, it is merely virtual.
An abstract method is one that has no base implementation and for which an implementation must be provided by a descendant.
In your case, simply declare them as virtual and provide them with the NO-OP (No operation) default implementation that your design dictates:
type
TMyBaseClass = class
protected
procedure SomeProc; virtual;
end;
procedure TMyBaseClass.SomeProc;
begin
// NO-OP
end;
Note - this illustrates my own personal convention of documenting a deliberate NO-OP, rather than just leaving an empty implementation.
Any shennanigans you go through to attempt to detect whether a declared abstract method has been overridden or not and to call it - or not - on the basis of that test is likely to cost more time than simply calling a NO-OP implementation. Plus, should you ever need to introduce an implementation in that base class you don't have to change the method from abstract to non-abstract (possibly disrupting those "detection" circuits you had w.r.t that method, and certainly rendering their cost as nothing but pure overhead).
Upvotes: 4
Reputation: 2666
If you got a line code like this:
lObj := TMyClass.Create;
you will notice that the compiler will output a warning saying that you are constructing instance of 'TMyClass' containing abstract method TMyClass.VAProc.
Upvotes: 1
Reputation: 11217
I think this is the wrong approach, it smells really really bad.. Some suggestions:
Upvotes: 4
Reputation: 2076
You can do something like this. Note that I've removed "abstract". It may work with "abstract" in place, but I haven't tried that.
type
TMyClass = class(TObject)
protected
procedure VProc; virtual;
procedure VAProc; virtual; //abstract;
end;
function GetVAProcAddress(Instance: TMyClass): pointer;
var
p: procedure of object;
begin
p := Instance.VAProc;
result := TMethod(p).Code;
end;
//in one of the TMyClass methods you can now write:
if GetVAProcAddress(self) <> @TMyClass.VAProc then
Upvotes: 3
Reputation: 12729
Use RTTI to get the method address of the virtual method in question for the class in questions. Compare it to the method address for the same method of the base class. If it is not the same, then the method was overriden.
Upvotes: 1