必须在多级继承中定义纯虚

Having to define pure virtual in mutli-level inheritance

本文关键字:定义 继承 多级      更新时间:2023-10-16

我有一个多层类层次结构,顶层有一个抽象基类。在层次结构的中层实现纯虚函数是没有意义的,但是如果没有它,编译就会失败。请参阅下面的示例和嵌入式代码注释。

我得到错误,如"对虚表的未定义引用"或"不能分配,因为函数是纯的",这取决于包含哪些行。它工作的唯一方法是如果我在D1中实现setValue方法,即使它在那里不适用。

我发现了一些类似的帖子,但没有发现任何回答这个具体情况。正如你可能知道的,我是c++/OOP的新手。

谢谢你看一看。

#include <string>
#include <iostream>
//  abstract base class
class AB { 
public:
    virtual void setName(std::string s) = 0;
    // Doesn't compile if I don't have this:
    // Different error if pure or non-pure
    virtual void setValue(int value) = 0;
};
class D1 : public AB {
public:
  // Doesn't compile if I don't have this line, but it's
  // not applicable to D1.
  //
  //void setValue(int value) { }
    void setName(std::string s) {
      std::cout << "D1::setName to " << s << std::endl;
      name_ = s;
    }
private:
  std::string name_;
};
class D2 : public D1 { 
public:
  void setValue(int value) {
      std::cout << "D2::setValue to " << value << std::endl;
      val_ = value;
    }
private:
  int val_;
};
int main() {
    AB* pD1= new D1;
    AB* pD2= new D2;
    pD1->setName("a D1");
    pD2->setName("a D2");
    pD2->setValue(5);
  return 0;
}

您必须提供可能出现在具体类级别的所有虚纯方法的实现——对于具体类,构造函数是用new或变量定义调用的——

如果您没有在D1的级别提供void setValue(int value) { },则会出现这种情况,错误为

"不能分配,因为函数是纯的"

如果您不想提供D1::setValue,您应该提供一个默认值虚拟void AB::setValue(int value) {}的实现。错误

"对虚表的未定义引用"

来自缺失的实现。您已经声明了void AB::setValue(int value);,但没有为它提供任何实现。因为它是一个虚方法,链接器会报错这个消息。

AB* pD1= new D1;

构造一个D1。为了使D1是可构造的,它必须实现它的所有基类。

virtual void setName(std::string s) = 0; // implemented by D1
virtual void setValue(int value) = 0; // not implemented by D1

D1没有实现setValue,这是不完整的。

解决方案:如果您希望有D1的实例,并且AB的用户能够使用setValue,则实现setValue。没有其他选择。如果AB的用户永远不会使用setValue,那么从AB中删除它。不要抽象或暴露你不打算使用的东西。

离题推荐:

实现析构函数,即使它们什么都不做。默认析构函数不是虚函数,这将导致在确保销毁正确的子对象而不是基类时出现问题。