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
精彩评论