继承、纯虚函数和非内联成员函数定义

Inheritance, pure virtual functions and non-inline member function definitions

本文关键字:函数 成员 定义 继承      更新时间:2023-10-16

我把我的问题归结为以下代码,全部在一个*.cpp文件中:

class A {
public:
    A() {};
    int PerformAction() {
        return Action();
    }
protected:
    virtual int Action();
}
class B: public A {
protected:
    int Action();
}
int B::Action() {
   return 4;
}
int main() {
    B newB;
    newB.PerformAction();
};

前面的代码抛出一个Unresolved external symbol error on B::Action()。将a::Action()的定义更改为:

virtual int Action() = 0;

在main函数中使用时产生Cannot instantiate abstract class编译错误。我看到的所有答案都与将代码分散在多个文件中有关,但这都发生在一个源文件中。我想这与BAction()的实现在B的类定义之外有关,但我看不出它为什么会导致任何错误。

您的错误消息,放在一起,表明A::ActionB::Action之间的签名不匹配,这样B::Action不会成为覆盖。签名必须完全匹配(包括thiscv-qualification),除了允许返回类型协方差。

B::Action必须为virtual。如果签名匹配,它将是隐式的,除非它是模板。模板不能重写。

如果您有c++ 11编译器,我建议使用override关键字,使签名不匹配成为编译错误。

前面的代码在B::Action()上抛出了一个未解决的外部符号错误。

实际上,必须定义所有非纯虚函数,以便将它们的地址存储在该类的虚函数表中。

产生不能实例化抽象类编译器错误

不,它没有:http://ideone.com/IS7PJj

如果你试图直接实例化A,或者一个没有覆盖纯虚函数的子类,你会得到这个错误。B不覆盖它,所以不是抽象的。

可能,你真正的类BAction有一个不正确的签名,所以它实际上并没有覆盖在A中声明的那个。在c++ 11中,您可以将override说明符添加到B中,以在这种情况下获得更有用的错误信息。

我想这与BAction()的实现在B的类定义之外有关

不,这应该不是问题,只要函数只有一个定义。