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

时间:2017-10-19 20:49:22

标签: c++ class oop inheritance abstract-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;
}

当然,这段代码没有编译,但它将错误放在行Bar myVariable,说我无法实例化一个抽象类(因为我忘了覆盖{{1 },someMethod是抽象的)。但是我觉得如果编译器告诉我哪个方法我忘了覆盖它会更有帮助,因为我在BarFoo都有很多其他的东西,所以找到我忘记的方法覆盖,我必须通过Bar中的每个纯虚拟方法,并确保它在Foo中被覆盖,这需要花费很多时间。

所以我想知道我是否可以告诉编译器Bar不应该是抽象的,所以不要将编译器错误放在我声明类型{的变量的行上{1}}说Bar是抽象的(这不是非常有用),它将编译器错误置于Bar的声明中,说出类似"你忘了覆盖{ {1}}&#34 ;.像这样:

Bar

我做了一些研究,发现应用于某个类的final关键字确实可以继承该类。我尝试将Bar标记为someMethod,认为拥有一个无法继承的抽象类是没有意义的,但在XCode中我所得到的只是一个警告说"摘要课程标记为“最终”'" (但它仍然没有告诉我我忘记覆盖的方法),并且在Visual Studio中它没有改变任何东西,它甚至没有产生警告。即使它有效,它也不会完美,因为我没有反对从nonabstract class Bar: public Foo { //Error here, Bar isn't supposed to be abstract but I didn't override someMethod //Some stuff }; 继承的课程,我只是不希望Bar是抽象的。

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

3 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:7)

从C ++ 17开始,您可以使用Private Function MyHex(ByVal TempDec As Double) As String Dim TNo As Integer MyHex = "" Do TNo = TempDec - (Fix(TempDec / 16) * 16) If TNo > 9 Then MyHex = Chr(55 + TNo) & MyHex Else MyHex = TNo & MyHex End If TempDec = Fix(TempDec / 16) Loop Until (TempDec = 0) End Function 来确保某个类不是std::is_abstract<T>的抽象类:

static_assert

这并不能告诉您忘记覆盖哪些功能,但即使在未使用static_assert(!std::is_abstract<Bar>(), "Bar must be non-abstract."); 的情况下,也可以让您中断编译。当Bar是与使用它的代码分开编译的库的一部分时,这可能会有所帮助。

答案 2 :(得分:0)

我想你要确保Bar不是抽象的而不需要尝试实例化它。为此,您可以使用static_assert std::is_abstract

class Bar: public Foo {
    //Other stuff, but I forgot to override someMethod
};
static_assert(!std::is_abstract<Bar>(), "Bar is ought to be not abstract.");

这会在static_assert处给您编译错误;如果您实施someMethod(在BarFoo中),则编译器错误将消失。