如何检查Delphi类是否声明为抽象类?

发布于 2024-07-20 11:18:22 字数 255 浏览 8 评论 0原文

在Delphi中是否可以使用RTTI(或其他东西)来检查一个类是否被声明为抽象类? 就像是:

TMyAbstractClass = class abstract(TObject)
  // ...
end;

...

if IsAbstract(TMyAbstractClass.ClassInfo) then
  ShowMessage('Yeah')
else
  ShowMessage('Computer says no...');

Is it possible in Delphi to use RTTI (or something else) to check if a class is declared as abstract?
Something like:

TMyAbstractClass = class abstract(TObject)
  // ...
end;

...

if IsAbstract(TMyAbstractClass.ClassInfo) then
  ShowMessage('Yeah')
else
  ShowMessage('Computer says no...');

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜嗑 2024-07-27 11:18:22

我没有足够新的版本来直接回答您的问题,但请记住,类是否是抽象的实际上并不重要。 所做的只是让编译器阻止您直接在类上调用构造函数。 如果将类引用放入类引用变量中,编译器将允许您调用该变量的构造函数,并且在运行时您将拥有一个假定不可实例化的类的实例。

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

真正重要的是类是否有抽象方法。 您可以很容易地检查这一点。 查看班级的 VMT。 任何包含指向 System._AbstractError 的指针的虚拟方法槽都是抽象方法。 棘手的部分是知道要检查多少个虚拟方法槽,因为这没有记录。 Allen Bauer 演示了如何在对 另一个问题,但在评论中 Mason Wheeler 指出它可能返回比应有的更大的值。 他提到了 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;

如果一个抽象类没有抽象方法,那么它到底能有多抽象? 它必须被标记为抽象,以防止开发人员创建它的实例,但如果您真的愿意,您无论如何都可以创建它的实例,因此标记抽象类实际上更多的是警告,而不是对使用的任何实际限制。

I don't have a version recent enough to answer your question directly, but keep in mind that it doesn't really matter whether the class is abstract. All that does is make the compiler stop you from calling a constructor directly on the class. If you put the class reference into a class-reference variable, the compiler will allow you to call the constructor on the variable, and at run time you'll have an instance of the supposedly uninstantiable class.

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

What's really important is whether the class has any abstract methods. You can check for that fairly easily. Look in the class's VMT. Any virtual-method slot that contains a pointer to System._AbstractError is an abstract method. The tricky part is knowing how many virtual-method slots to check, since that isn't recorded. Allen Bauer demonstrated how to do that in an answer to another question, but in the comments Mason Wheeler points out that it may return larger values than it should. He mentions the GetVirtualMethodCount function from the JCL, which should give a more accurate count of user-defined virtual methods. Using that function and GetVirtualMethod, also from the JCL, we get this function:

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;

If an abstract class has no abstract methods, then how abstract can it really be? It must have been marked abstract to prevent developers from creating instances of it, but if you really want to, you can create instances of it anyway, so marking an abstract class is really more of a warning than any actual restriction on usage.

撧情箌佬 2024-07-27 11:18:22

快速浏览 TypInfo 单元不会发现任何有用的信息。 我认为“抽象类”的概念纯粹是为了编译器的利益。 它给它一个强制执行的规则——没有这个类的实例化,只有它的后代——但在运行时并没有真正做任何事情,所以不需要为它记录任何RTTI。

你为什么只是出于好奇而试图找出这一点?

A quick look through the TypInfo unit doesn't turn up anything helpful. I think the notion of an "abstract class" is purely for the compiler's benefit. It gives it a rule to enforce--no instantiation of this class, only its descendants--but doesn't really do anything at runtime, so there's no need to record any RTTI for it.

Why are you trying to find this out anyway, just out of curiosity?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文