Delphi: how to make multiple virtual methods reference the same function?

I have an abstract iterator class:

TImageIterator = class (TObject)
  protected
    fCurLine, fCurPos: Integer;
  public
    //also basic constructors here, etc.
    function ReadNextPixel: Cardinal; virtual; abstract;
    function ReadNextAsGrayscale: Cardinal; virtual; abstract;
    function ReadNextSubpixel: Cardinal; virtual; abstract;
end;

and many descendants, say, T1BitImageIterator, T4BitImageIterator, T8BitImageIterator, T24BitRGBImageIterator. The point is to create an iterator (over a non-rectangular area) suitable for the current image / pixel format, and then process the image regardless of its type.

ReadNextPixel returns "raw pixel data": 0 or 1 in a 1-bit image, 0..255 in an 8-bit image, or some kind of TColor in 24-bit RGB.

ReadNextAsGrayscalereturns the brightness of a pixel in the range 0..255, which in the case of an 8-bit image will be the same as ReadNextPixel.

ReadNextSubpixel , ReadNextPixel /, R, ( ) G, B 24- RGB-.

:

function T8BitImageIterator.ReadNextPixel: Cardinal;
begin
  Result:=fByteLine[fCurPos];
  inch(fCurPos);
  if fCurPos=fRight then begin
    //going to next scanline, checking for end of iterated area etc
  end;
end;

//another 'unique' functions

//code we'd be happy to get rid of
function T8BitImageIterator.ReadNextAsGrayscale: Cardinal;
begin
  Result:=ReadNextPixel;
end;

function T1BitImageIterator.ReadNextSubpixel: Cardinal;
begin
  Result:=ReadNextPixel;
end;

function T4BitImageIterator.ReadNextSubpixel: Cardinal;
begin
  Result:=ReadNextPixel;
end;

function T8BitImageIterator.ReadNextSubpixel: Cardinal;
begin
  Result:=ReadNextPixel;
end;

, , !

, :

  T8BitImageIterator = class (TImageIterator)
    public
      function ReadNextPixel: Cardinal; override;
      function ReadNextAsGrayscale=ReadNextPixel; override;
      ...
  end;

, , .

, , . ,

TReadNextPixelProc = function: Cardinal of object;

TImageIterator = class(TObject)
  ...
  public
    ReadNextAsGrayscale: TReadNextPixelProc;
    ...
 end;

, ( , TReadNextPixelProc ..).

:

function T8BitImageIterator.ReadNextAsGrayscale: Cardinal;
asm
  jmp ReadNextPixel;
end;

ReadNextPixel ReadNextAsGrayscale, , ReadNextPixel..

: , VMT , , " " . ?

+4
2

, , . , , , .

, . / , Delphi . VMT, . , .

+3

, ,

. - , , , , .

, , . , , , .

- . , , . :

type
  IImageIterator = interface
    function ReadNextPixel: Cardinal;
    function ReadNextAsGrayscale: Cardinal;
    function ReadNextSubpixel: Cardinal;
  end;

  TImageIteratorBase = class(TInterfacedObject, IImageIterator)
  protected
    fCurLine, fCurPos: Integer;
  public
    //basic constructors here, etc.
    function DoReadNext: Cardinal; virtual; abstract;
    function IImageIterator.ReadNextPixel = DoReadNext;
    function IImageIterator.ReadNextAsGrayscale = DoReadNext;
    function IImageIterator.ReadNextSubpixel = DoReadNext;
  end;

  T1BitImageIterator = class(TImageIteratorBase, IImageIterator)
  public
    function DoReadNext: Cardinal; override;
    // implement IImageIterator methods if needed...
  end;

  T4BitImageIterator = class(TImageIteratorBase, IImageIterator)
  public
    function DoReadNext: Cardinal; override;
    // implement IImageIterator methods if needed...
  end;

  T8BitImageIterator = class(TImageIteratorBase, IImageIterator)
  public
    function DoReadNext: Cardinal; override;
    // implement IImageIterator methods if needed...
  end;

  T24BitRGBImageIterator = class(TImageIteratorBase, IImageIterator)
  public
    function DoReadNext: Cardinal; override;
    // implement IImageIterator methods if needed...
  end;

...

function T1BitImageIterator.DoReadNext: Cardinal;
begin
  //...
end;

function T4BitImageIterator.DoReadNext: Cardinal;
begin
  //...
end;

function T8BitImageIterator.DoReadNext: Cardinal;
begin
  Result:=fByteLine[fCurPos];
  inch(fCurPos);
  if fCurPos=fRight then begin
    //going to next scanline, checking for end of iterated area etc
  end;
end;

function T24BitImageIterator.DoReadNext: Cardinal;
begin
  //...
end;

DoReadNext(), override . -, , . :

type
  ...
  T24BitRGBImageIterator = class(TImageIteratorBase, IImageIterator)
  public
    function DoReadNext: Cardinal; override;
    // implement IImageIterator methods if needed...
    function ReadNextAsGrayscale: Cardinal;
  end;

function T24BitRGBImageIterator.DoReadNext: Cardinal;
begin
  //...
end;

function T24BitRGBImageIterator.ReadNextAsGrayscale: Cardinal;
begin
  //...
end;

, . VMT , .

+4

Source: https://habr.com/ru/post/1621554/


All Articles