Как проверить, объявляется ли класс Delphi кратким обзором?

Я использую Postgres. Не уверен, работает ли это решение для других баз данных. Таблица people используется в качестве примера - не забудьте изменить имя таблицы на свое.

  def up
    change_column :people, :permanent, 'integer USING CAST(permanent AS integer)'
    Person.connection.execute("UPDATE people SET permanent = CASE permanent WHEN 0 THEN 1 WHEN 1 THEN 2 END")
  end

  def down
    Person.connection.execute("UPDATE people SET permanent = CASE permanent WHEN 1 THEN 0 WHEN 2 THEN 1 END")
    change_column :people, :permanent, 'boolean USING CAST(permanent AS boolean)'
  end
6
задан mrMoo 12 May 2009 в 12:19
поделиться

2 ответа

Быстрый просмотр блока TypInfo не дает ничего полезного. Я думаю, что понятие «абстрактный класс» предназначено исключительно для выгоды компилятора. Он дает ему обязательное правило - не создавать экземпляров этого класса, только его потомки - но на самом деле ничего не делает во время выполнения, поэтому нет необходимости записывать для него RTTI.

Почему вы пытаетесь найти это все равно, просто из любопытства?

0
ответ дан 17 December 2019 в 02:33
поделиться

У меня недостаточно свежей версии, чтобы напрямую ответить на ваш вопрос, но имейте в виду, что на самом деле не имеет значения, является ли класс абстрактным. Все, что это делает, - это заставляет компилятор мешать вам вызывать конструктор непосредственно в классе. Если вы поместите ссылку на класс в переменную ссылки на класс, компилятор позволит вам вызвать конструктор переменной, и во время выполнения у вас будет экземпляр предположительно неустановленного класса.

var
  c: TClass;
  o: TObject;
begin
  c := TMyAbstractClass;
  o := c.Create;
  Assert(o is TMyAbstractClass);
end;

Что действительно важно, так это , есть ли у класса какие-либо абстрактные методы . Вы можете легко это проверить. Посмотрите в VMT класса. Любой слот виртуального метода, содержащий указатель на System. _AbstractError - абстрактный метод. Сложная часть - знать, сколько слотов виртуальных методов нужно проверить, поскольку это не записывается. Аллен Бауэр продемонстрировал, как это сделать в ответе на другой вопрос , но в комментариях Мейсон Уиллер указывает, что он может возвращать большие значения, чем должен. Он упоминает функцию GetVirtualMethodCount из JCL , которая должна давать более точное количество определяемых пользователем виртуальных методов. Используя эту функцию и GetVirtualMethod , также из JCL, мы получаем эту функцию:

function HasAbstractMethods(c: TClass): Boolean;
var
  i: Integer;
begin
  Result := True;
  for i := 0 to Pred(GetVirtualMethodCount(c)) do
    if GetVirtualMethod(c, i) = @_AbstractError then
      exit;
  Result := False;
end;

Если абстрактный класс не имеет абстрактных методов, то насколько абстрактным он может быть на самом деле? Он должен быть помечен как абстрактный, чтобы разработчики не могли создавать его экземпляры, но если вы действительно хотите, вы все равно можете создавать его экземпляры,

6
ответ дан 17 December 2019 в 02:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: