我可以强制C++类是非抽象的吗?

Don*_*uck 3 c++ oop inheritance abstract-class class

在我的C++程序中,我有一个名为的抽象类Foo和一个从它继承的类,它Bar不应该是抽象的.但我经常添加纯虚方法Foo,忘记覆盖它们Bar,这Bar也是一个抽象类.所以我经常得到这样的代码:

class Foo {
public:
    virtual void someMethod() = 0;
    //Other stuff
};

class Bar: public Foo {
    //Other stuff, but I forgot to override someMethod
};

int main(){
    Bar myVariable;    //Error here saying that Bar is abstract
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然,这段代码没有编译,但它把错误放在了一行Bar myVariable,说我无法实例化一个抽象类(因为我忘了覆盖someMethod,Bar是抽象的).但我认为这将是更有益的,如果编译器告诉我,我忘了哪一种方法来替代,因为我在这两个有很多其他的事情Foo,并Bar因此发现我忘了重写,我会用什么方法去通过每个纯虚拟方法Foo并确保它被覆盖Bar,这需要花费很多时间.

所以我想知道我是否可以告诉编译器Bar不应该是抽象的,所以不要把编译器错误放在我声明类型的变量Bar说明Bar是抽象的行(这不是很有帮助) ),它将编译器错误放在Bar说"你忘了覆盖someMethod"之类的声明中.像这样的东西:

nonabstract class Bar: public Foo { //Error here, Bar isn't supposed to be abstract but I didn't override someMethod
    //Some stuff
};
Run Code Online (Sandbox Code Playgroud)

我做了一些研究,发现final应用于类的关键字确实无法继承该类.我试着标记Barfinal,认为有一个不能继承的抽象类是没有意义的,但在XCode中我得到的是一个警告,说"抽象类标记为'最终'"(但它仍然没有告诉我忘了覆盖什么方法),在Visual Studio中它没有改变任何东西,它甚至没有产生警告.即使它工作也不完美,因为我没有反对继承的类Bar,我只是不想Bar抽象.

有没有办法告诉编译器Bar不应该是抽象的,所以当我忘记覆盖纯虚方法并告诉我忘记覆盖哪种方法时,它会给我一个错误?

Sne*_*tel 9

在某些IDE中,特别是Visual Studio,"错误"窗口仅显示每个错误的第一行.如果查看编译器输出,它会显示其他信息(如果有); 在这种情况下,该信息将包括成员丢失的内容(您可以双击输出行以转到相关的代码行).我不知道最近的编译器没有告诉你哪些抽象函数未实现.


das*_*ght 7

从C++ 17开始,您可以使用static_assert以确保某个类不是抽象的std::is_abstract<T>:

static_assert(!std::is_abstract<Bar>(), "Bar must be non-abstract.");
Run Code Online (Sandbox Code Playgroud)

这并不能告诉您忘记覆盖哪些函数,但即使在Bar未使用的情况下也可以打破编译.当Bar这是与使用它的代码分开编译的库的一部分时,这可能会有所帮助.

  • 但这有什么帮助呢?如果我正确地阅读了这个问题,那么OP希望被告知他们忘了覆盖哪些功能. (5认同)
  • @juanchopanza"我想知道我是否可以告诉编译器Bar不应该是抽象的" (2认同)