sud03r
sud03r

Reputation: 19799

Why I have to redeclare a virtual function while overriding [C++]

#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

Answers (7)

xtofl
xtofl

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

anon
anon

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

Ben Burnett
Ben Burnett

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

the_drow
the_drow

Reputation: 19201

The redeclaration is needed because:

  • The standard says so.
  • It makes the compiler's work easier by not climbing up the hierarchy to check if such function exists.
  • You might want to declare it lower in the hierarchy.
  • In order to instantiate the class the compiler must know that this object is concrete.

Upvotes: 25

aJ.
aJ.

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

Pace
Pace

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

GalacticCowboy
GalacticCowboy

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

Related Questions