我在单个* .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
的类定义有关,但无法找出导致任何错误的原因。
答案 0 :(得分:2)
前面的代码在
B::Action()
上抛出了一个未解决的外部符号错误。
实际上,必须定义所有非纯虚函数,以便它们的地址可以存储在类的虚函数表中。
而不是实例化抽象类编译器错误
如果您尝试直接实例化A
或未覆盖纯虚函数的子类,则会出现该错误。 B
会覆盖它,因此不是抽象的。
可能您的真实班级B
的{{1}}签名不正确,因此它实际上并没有覆盖Action
中声明的签名。在C ++ 11中,您可以将A
说明符添加到override
中的说明符,以便在这种情况下获得更有用的错误消息。
我认为这与
B
B
的{{1}}的类定义之外的实现有关{/ 1}}
不,这不应该是一个问题,只要该功能只有一个定义。
答案 1 :(得分:2)
您的错误消息一起表示A::Action
和B::Action
之间的签名不匹配,因此B::Action
不会成为覆盖者。签名必须完美匹配(包括this
的 cv-qualification ),但允许返回类型协方差。
B::Action
必须是virtual
。如果签名匹配,则隐含地,除非它是模板。模板无法覆盖。
如果你有一个C ++ 11编译器,我建议使用override
关键字,使签名不匹配成为编译错误。