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

时间:2014-03-12 14:55:16

标签: c++ inheritance unresolved-external pure-virtual

我在单个* .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;

产生Cannot instantiate abstract class编译器错误,它在main函数中使用。我所看到的所有答案都涉及将代码分布在多个文件中,但这一切都发生在一个源文件中。我认为这与B Action()的{​​{1}}类定义超出B的类定义有关,但无法找出导致任何错误的原因。

2 个答案:

答案 0 :(得分:2)

  

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

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

  

而不是实例化抽象类编译器错误

不,不是:http://ideone.com/IS7PJj

如果您尝试直接实例化A或未覆盖纯虚函数的子类,则会出现该错误。 B会覆盖它,因此不是抽象的。

可能您的真实班级B的{​​{1}}签名不正确,因此它实际上并没有覆盖Action中声明的签名。在C ++ 11中,您可以将A说明符添加到override中的说明符,以便在这种情况下获得更有用的错误消息。

  

我认为这与B B的{​​{1}}的类定义之外的实现有关{/ 1}}

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

答案 1 :(得分:2)

您的错误消息一起表示A::ActionB::Action之间的签名不匹配,因此B::Action不会成为覆盖者。签名必须完美匹配(包括this cv-qualification ),但允许返回类型协方差。

B::Action必须是virtual。如果签名匹配,则隐含地,除非它是模板。模板无法覆盖。

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