我试图创建一个简单的抽象基类,它包含一个虚函数和一个定义该虚函数的子类。运行下面的代码会在编译过程中产生错误:
#include <iostream>
using namespace std;
class Animal {
public:
virtual void speak();
};
class Cat : public Animal{
public:
void speak() override {
cout << "Meow!";
}
};
int main() {
Cat cat;
Animal* base = &cat;
base->speak();
}
// error LNK2001: unresolved external symbol "public: virtual void __thiscall Base::speak(void)" (?speak@Base@@UAEXXZ)
我的IDE建议在Animal中为speak()添加一个无用的定义,它起作用了:
#include <iostream>
using namespace std;
class Animal {
public:
virtual void speak();
};
void Animal::speak() {
}
class Cat : public Animal{
public:
void speak() override {
cout << "Meow!";
}
};
int main() {
Cat cat;
Animal* base = &cat;
base->speak();
}
那么,为什么我必须在基类中定义虚函数呢?
相比之下,在Java中没有这样的需要,甚至没有这样的可能性(这更有意义):
abstract class Animal {
abstract void speak();
}
class Cat extends Animal {
void speak() {
System.out.println("Meow!");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Cat();
animal.speak();
}
}
3条答案
按热度按时间pw9qyyiw1#
是,需要定义非纯虚函数。
[类.虚拟]/12:
类中声明的虚函数应在该类中定义或声明为纯函数(class.abstract(https://timsong-cpp.github.io/cppwp/class.abstract)),或同时定义和声明;不需要诊断(basic.def.odr(https://timsong-cpp.github.io/cppwp/basic.def.odr))。
您可以提供一个定义,或者将其标记为纯虚拟。
6jygbczu2#
您需要使用
= 0
在基类中将其标记为“abstract”(或C++术语中的“pure virtual”)。nkoocmlb3#
在C++中,如果一个类至少有一个纯虚函数,那么它就是抽象的。
这个班
不是抽象类,因为该类中未声明纯虚函数。
虚函数通过在类定义的函数声明中使用pure说明符来指定为pure。
也就是说,要使类抽象化,应该声明其虚函数,如下所示
编译器需要建立一个指向虚函数的指针表,其中存储虚函数的实际地址。如果链接器无法解析虚函数的地址,则会发出错误。
请记住,可以定义纯虚函数。例如,您可以编写
在派生类中,您可以按以下方式定义函数