【问题标题】:Inheritance, pure virtual functions and non-inline member function definitions [closed]继承、纯虚函数和非内联成员函数定义
【发布时间】:2014-04-16 19:30: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;

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

【问题讨论】:

  • 这显然不是您正在编译的代码 - 缺少分号并尝试调用受保护的函数会在您报告链接器错误之前给出编译器错误。一旦我修复了这些错误,并按照您的描述使函数成为纯虚拟函数,就没有错误:ideone.com/IS7PJj
  • 另外,请不要在发布的代码中添加行号;为了测试它而不得不移除它们是一种痛苦。
  • 另外,main 必须返回 int
  • 为了了解您收到错误的原因,我们需要演示错误的代码。此代码有不同的错误(缺少分号,main 的类型错误),并在修复这些错误后干净地编译。没有办法知道您的代码可能有什么问题。大概它正在尝试实例化A,但除此之外我无法猜测。
  • 因此将其简化为显示相同错误的代码。上面的代码甚至没有表现出你声称的错误。至少,尝试编译/链接/运行您在此处发布的代码,并报告实际代码中的错误,而不是您未向我们展示的其他代码。

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


【解决方案1】:

综合起来,您的错误消息表明A::ActionB::Action 之间的签名不匹配,因此B::Action 不会成为替代者。签名必须完全匹配(包括thiscv-qualification),但允许返回类型协变。

并且B::Action 必须是virtual。如果签名匹配,它将是隐式的,除非它是一个模板。模板不能覆盖。

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

【讨论】:

  • 漂亮,这是我需要的提示。我正在使用 VC++ Express 2008,不确定里面有什么编译器。问题是在函数实现上对 template 进行了一些不必要的调用,这使得它们没有真正被覆盖。
  • @JCollins:模板函数永远不是虚拟的,所以这听起来像你的问题。
  • 这就是我正在学习的内容。幸运的是,问题解决了,我现在可以编译了。干杯。
【解决方案2】:

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

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

导致无法实例化抽象类编译器错误

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

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

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

我想这与BAction() 实现超出B 的类定义有关

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

【讨论】:

  • 我想这是我的困惑,在我的代码 B 中肯定实现了 Action(),(或者它是现实世界的等价物),尽管我仍然收到该错误。我相信你的意思是,在其他地方寻找问题,因为它不是特定结构和用法选择的函数。
  • Indeed, all non-pure virtual functions must be defined, so that their address can be stored in the virtual function table for the class. 而且,更抽象地说,它们可以被调用!
  • @LightnessRacesinOrbit:是的;但是(与大多数函数不同)即使未调用它们也必须定义它们。
猜你喜欢
  • 2012-08-06
  • 1970-01-01
  • 2015-08-07
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 2010-10-02
  • 1970-01-01
相关资源
最近更新 更多