Вызов абстрактной функции Delphi с именем, отличным от базового класса - PullRequest
1 голос
/ 04 февраля 2011

скажем, у меня есть функция

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

и я пытаюсь добавить

function GetFieldNameA(FieldIndex: Integer; FieldName: PAnsiChar; 
    Len: Integer): Integer;

Что временно соединит мою базу данных с Unicode.

Я хочу продолжить вызывать GetFieldName, сделать его не абстрактным и выполнить некоторую битовую типизацию для вызова GetFieldNameA, который станет технически абстрактной версией первого GetFieldName. (Я не хочу менять базовый класс вообще)

Есть ли способ, например, добавить ключевое слово name для внешних ссылок, иметь абстрактную функцию с другим именем в подклассе?

То, что я представляю себе в итоге, выглядит примерно так:

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

Ответы [ 2 ]

6 голосов
/ 04 февраля 2011

Нет, вы не можете делать то, что предлагаете.

Вместо этого переопределите GetFieldName. Пусть он преобразует PChar в PAnsiChar (при необходимости) перед вызовом GetFieldNameA. Последний не обязательно должен быть (и не может быть) отмечен override. Это может быть обычная не виртуальная функция.

Неудачная часть этого предложения заключается в том, что вам придется делать это в каждом классе-потомке. Альтернативой является добавление виртуального абстрактного GetFieldNameA в базовый класс, а затем изменение всех потомков, чтобы переопределить его вместо GetFieldName. Измените GetFieldName в базовом классе на вызов GetFieldNameA. Но это не стартер, если вы не можете изменить базовый класс.

1 голос
/ 05 февраля 2011

Если я правильно понял ваш вопрос, вы можете обмануть Delphi, введя замененный базовый класс.

Если класс, который объявляет исходное GetFieldName, называется TClass1, объявленным в Unit1 (pas или dcu), то:

  • создает новый модуль (TrickUnit.pas).
  • В TrickUnit.pas добавьте модуль старого класса в раздел использований (TrickUnit.pas использует Unit1)
  • В TrickUnit.pas объявите класс с тем же именем, что и исходный класси заставьте его наследовать исходный класс type TClass1 = class(Unit1.TClass1)
  • , переопределить GetFieldName и добавить свою пользовательскую реализацию.
  • Просто добавьте TrickClass.pas в конце секции использования (интерфейсной части) каждого модуля, который ожидает оригинальный класс

Пока TrickUnit.pasв конце раздела использования все ваши потомки будут наследовать ваш замененный класс без изменений кода, кроме добавления using ......, TrickUnit

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...