必须在多级继承中定义纯虚
Having to define pure virtual in mutli-level inheritance
我有一个多层类层次结构,顶层有一个抽象基类。在层次结构的中层实现纯虚函数是没有意义的,但是如果没有它,编译就会失败。请参阅下面的示例和嵌入式代码注释。
我得到错误,如"对虚表的未定义引用"或"不能分配,因为函数是纯的",这取决于包含哪些行。它工作的唯一方法是如果我在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
中删除它。不要抽象或暴露你不打算使用的东西。
离题推荐:
实现析构函数,即使它们什么都不做。默认析构函数不是虚函数,这将导致在确保销毁正确的子对象而不是基类时出现问题。
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?
- 如何定义一个没有重复代码的继承的 const 类成员函数?
- 如何创建没有特定定义的随机分布?uniform_int_distribution是从其他类继承的吗?
- C++ 定义继承方案
- 从第三方定义的类继承时shared_from_this
- 自定义异常中的用户定义的空构造函数,具有多个继承和抽象基类
- 类继承自QLabel,为什么不调用自定义插槽?
- 继承依赖类型定义而不使用结构
- 如何正确消除继承类型定义的歧义?以及如何简化他们的创作?
- C++中的继承和构造函数定义
- 从模板继承的 MSVC DLL 导出类会导致LNK2005已定义的错误
- 模板化类继承的子类定义中的错误
- 定义多次继承的虚拟方法
- 继承中的函数定义
- C++对已继承的受保护类成员的未定义引用
- C 中的继承:在亲子类中定义变量
- 是否可以定义一个在外部"C"块中继承另一个结构的结构?
- 继承的模板化单例类 c++ 中未定义的构造函数
- 具有相同名称的抽象和已定义继承函数的多重继承