纯虚终函数:C++11中合法

26
class Foo
{
public: 
    virtual int foo() final = 0;
};

编译通过。

Foo 只是浪费空间,并且可能是一个意外吗?还是我有所遗漏?


在我看来,是的,在这种情况下,Foo是一个浪费空间的东西。 - Najzero
3
你有一个抽象类,无法实例化,但也永远无法从它派生出具体类... 恭喜? - Kerrek SB
我是指对于 dynamic_cast,你需要一个 vptr,而 foo() 确保了这一点。 - ipc
@ipc 动态转换(dynamic cast)是在哪些类型之间进行的? - Luchian Grigore
1
@onemasse:在源文件中浪费空间,因为你无法对其进行任何有意义的操作。 - Mike Seymour
显示剩余4条评论
3个回答

16

正如您所说,这几乎是完全浪费空间。但是至少有一个明显的用途。顺便说一句,它能编译通过并不奇怪。只要代码是合法的,它就不需要“有意义”才能编译。

假设您想将 Foo 用作策略。这意味着它将被用作模板参数,但不需要被实例化。实际上,您真的不希望任何人实例化该类(尽管我不知道为什么,因为它有什么影响)。

这正是您在这里拥有的东西。一个具有类型的类,但您无法实例化它(虽然将构造函数设置为私有可能会更加简单直接)。

额外的好处是,您可以在类范围内添加enum或静态函数。这些功能可以在不实例化的情况下使用,并且它们将位于该类的命名空间中。 因此,您拥有一个主要仅用作类型的类,但仍然以静态函数的形式捆绑了“一些功能”。

大多数情况下,人们可能只需将这些内容包装到命名空间中,但谁知道,在某些情况下,这可能是所需的方式。


6
即使你想要防止实例化,这样做也有点古怪。删除构造函数会更清晰地表达意图。 - Mike Seymour

10

Foo只是浪费空间吗?

确实是这样的;由于它是抽象的,你无法实例化它,也无法重写函数去创建一个非抽象的派生类。

如果你想要阻止一个类被实例化,它可以被用作一种方式;但即使如此,删除默认构造函数可能更有意义。

那么这不是一个错误的制作吗?

不完全是。由于你无法对该类做任何操作,因此你不会做出任何错误的行为。


我曾认为在指针和'->'方面可能会遇到麻烦,但忘记了此类别的任何对象都不会被创建。 - aiao

5
如果我正确理解9.2中的语法,这实际上是合法的,尽管我可能错过了一些在注释中禁止它的内容。
member-declarator: declarator virt-specifier-seq(opt) pure-specifier(opt)
然后它显示virt-specifier-seq可以是final,而pure-specifier是= 0。
我看不出这有任何用处,尽管可能存在某些边角情况会使用它。

你能想到一个“边角案例”吗? - aiao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接