开发者

Delphi abstract function calls with different name than base class

Say I've got a function

function GetFieldName(FieldIndex: Integer; FieldName: PChar; 
    Len: Integer): Integer; virtual; abstract;

and I'm trying to add

function GetFieldNameA(Fiel开发者_C百科dIndex: Integer; FieldName: PAnsiChar; 
    Len: Integer): Integer;

Which will temporarily bridge my database connection for unicode.

I want to continue to call GetFieldName, make it not abstract, and do some bit typecasting to call GetFieldNameA, which will become a technically abstract version of the first GetFieldName. (I don't want to change the base class at all)

Is there a way, like adding the 'name' keyword for external references, to have an abstract function with a different name in the subclass?

What I'm imagining ending up with is something like:

function GetFieldName(FieldIndex: Integer; FieldName: PChar; 
    Len: Integer): Integer; 
function GetFieldNameA(FieldIndex: Integer; FieldName: PAnsiChar;
    Len: Integer): Integer name 'GetFieldName Virtual Abstract'; 


No, you can't do what you're proposing.

Instead, override GetFieldName. Have it convert the PChar to a PAnsiChar (if necessary) before calling GetFieldNameA. The latter doesn't have to be (and can't, actually) be marked override. It can be an ordinary non-virtual function.

The unfortunate part of that suggestion is that you'd have to do it in every descendant class. The alternative is to add a virtual abstract GetFieldNameA to the base class and then change all the descendants to override that instead of GetFieldName. Change GetFieldName in the base class to call GetFieldNameA. But that's a non-starter if you can't change the base class.


If I understood your question correctly you can trick Delphi by injecting replaced base class.

If the class that declares original GetFieldName is called TClass1 declared in Unit1(pas or dcu), then:

  • make a new unit (TrickUnit.pas).
  • In the TrickUnit.pas add unit of the old class in the uses section (TrickUnit.pas uses Unit1)
  • In the TrickUnit.pas declare the class with the same name as the original class, and make it inherit the original class type TClass1 = class(Unit1.TClass1)
  • override GetFieldName and add your custom implementation.
  • Just add TrickClass.pas at the end of uses section (interface part) of each unit that expects original class

As long as TrickUnit.pas is at the end of uses section, all of your descendants will end up inheriting your replaced class with no code changes other than adding using ......, TrickUnit

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜