Reputation: 19799
#include <iostream>
using namespace std;
class Duck {
public:
virtual void quack() = 0;
};
class BigDuck : public Duck {
public:
// void quack(); (uncommenting will make it compile)
};
void BigDuck::quack(){ cout << "BigDuckDuck::Quack\n"; }
int main() {
BigDuck b;
Duck *d = &b;
d->quack();
}
The code above doesn't compile. However, when I declare the virtual function in the subclass, then it compiles fine.
If the compiler already has the signature of the function that the subclass will override, then why is a redeclaration required?
Any insights?
Upvotes: 30
Views: 10423
Reputation: 41519
Because C++ separates 'declaration' from 'polymorphism': any function needs a declaration for the compiler, regardless if it's virtual or not.
Your example doesn't go far enough, it has the 'abstract class' problem: a BigDuck cannot be instantiated because it has no implementation of quack in it's interface.
Generalizing the problem, we can declare the base function not pure virtual:
class Duck { public: virtual void quack(){} };
class BigDuck : public Duck {};
// WRONG: undeclared method definition
void BigDuck::quack(){ cout << "QUACK!"; }
In here, the compiler will complain that it has a symbol BigDuck::quack
that wasn't declared. This has nothing to do with abstract classes or anything.
(Note: gcc says:
error: no 'void BigDuck::q()' member function declared in class 'BigDuck'
)
Upvotes: 7
Reputation:
Until you provide an implementation, all classes that inherit from a class that contains Pure Virtual Function
are abstract - they cannot be instantiated. In order to provide such an implementation, you must declare the function in the class.
Upvotes: 2
Reputation: 1564
If you change:
virtual void quack() = 0;
to
virtual void quack();
It will compile without implementing quack() in HugeDuck.
the = 0; at the end of the function declaration is essentially saying that all BigDucks will quack, but that it has to be implemented by each derived duck. By removing the = 0; the BigDuck quack will get called unless you implement quack in HugeDuck.
EDIT: To clarify the = 0; is saying that the derived class will have the definition for the function. In your example it is expecting HugeDuck to define quack(), but as you have it commented it out it does not.
As a side note, since all ducks can quack perhaps your original Duck class that we can not see should implement quack() instead?
Upvotes: 12
Reputation: 19201
The redeclaration is needed because:
Upvotes: 25
Reputation: 35490
Declaring the methods in each classes will tell the compiler that class provides the different implementation for the method.
Also,
in case you want to create the objects of BigDuck
on stack then how will compiler should know the signature of quack()
.
BigDuck aDuck;
aDuck.quack();
Upvotes: 1
Reputation: 43957
BigDuck could be another abstract class and you might not want to implement quack until you get to the base class ReallyBigDuck.
Upvotes: 2
Reputation: 11769
The definition of Quack()
in your base class is "abstract" - it has no implementation. This tells the compiler that your derived class must implement it. Failure to do so is a compilation error.
Upvotes: 2