I'm trying to create a simple base abstract class with a virtual function and a child class that defines that virtual function. Running the following produces an error during compilation:
#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)
My IDE suggests adding a useless definition for speak() in Animal, and it works:
#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();
}
So, why do I have to define virtual function in a base class?
By comparison, in Java there is no such need and even possibility (which makes more sense):
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();
}
}
Yes, non-pure virtual function should be defined.
A virtual function declared in a class shall be defined, or declared pure ([class.abstract]) in that class, or both; no diagnostic is required ([basic.def.odr]).
You might provide a definition, or mark it as pure virtual.
class Animal {
public:
virtual void speak() = 0;
};