Jerry Dodge
Jerry Dodge

Reputation: 27276

How to make sure a future inheritance overrides a procedure?

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

Answers (5)

Deltics
Deltics

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

Henrick Hellström
Henrick Hellström

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

dummzeuch
dummzeuch

Reputation: 11217

I think this is the wrong approach, it smells really really bad.. Some suggestions:

  • Use non-abstract methods that do what you want to do when they are not overridden.
  • Use events instead of methods. It's easy to check whether they have been assigned.

Upvotes: 4

Giel
Giel

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

Sean B. Durkin
Sean B. Durkin

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

Related Questions