Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I have to re-declare overridden functions in derived classes in c++?

Suppose I have the following code:

class Iinterface
{
  virtual void abstractFunction()=0;
};

class Derived : public Iinterface
{
  void abstractFunction(); // Do I need this line?
};

Derived::abstractFunction()
{
  // implementation here
}

If I don't add the line in question, I get compile error which says abstractFunction is not declared in Derived. I'm using VS 2008.
I'm not sure why I need this particular line (do not confuse this with the function definition which is provided outside class declaration), as long as I'm inheriting from Iinterface it should be obvious I have abstractFunction declared. Is that a problem with visual studio or is it enforced by c++ standards?

like image 741
atoMerz Avatar asked Nov 19 '12 06:11

atoMerz


3 Answers

If the declaration of pure-virtual base functions were implied in all derived classes, then you could never have a derived class that remains abstract with respect to a pure-virtual base function. Instead, all derived classes would produce linker errors. That would be extremely counter-intuitive and confusing, and it would make the language less expressive.

Moreover, it wouldn't even make sense: The question whether the derived class is abstract or not must be known everywhere at compile-time. The implementation of the overrider is typically only provided in one single translation unit, so it would be impossible to communicate the fact that you actually mean for the function to be overridden to the rest of the program.

like image 103
Kerrek SB Avatar answered Nov 07 '22 02:11

Kerrek SB


  1. Yes: If you want to create an object of the class Derived
  2. No: If you want to keep the class Derived also abstract
  3. No: If there is an intermediate class which has already overridden the function
    e.g. between Iinterface and Derived there is a class Intermediate which has overridden abstractFunction(); so now it's optional for class Derived to override the same

Edit: With the changed question title,

Why do I have to re-declare overridden functions in derived classes in c++?

That's because C++ compiler grammar demands that every member function of the class (or namespace or file) must be declared inside the class (or namespace or file) body. Be it virtual or normal function.
There is no good reason for breaking that consistency just for virtual functions.

like image 24
iammilind Avatar answered Nov 07 '22 03:11

iammilind


A function that ends in an =0 is called a deleted function, this is useful when you don't want objects that use certain constructors (such as unique_ptr which has a deleted copy ctor).

If a virtual function is deleted then by standard the class becomes an abstract type. Because in most cases the prototype of a class and the class's function bodies are in separate files, this means that unless you explicitly outline in the prototype that you're overriding the deleted virtual function then you're NOT overriding the deleted virtual function. The compiler isn't supposed to just simply infer that you meant to put the function in there once it sees the implementation in a completely different file.

Remember that the prototype/implementation idea isn't the only way to write code, you can also put the implementation right in the class (which can be done if the code is small enough and you want to inline the function.) And to do that you need to again, explicitly override the deleted virtual function. So because you need to override it anyway, it makes perfect sense that you need to explicitly override it in the prototype. The function is still deleted otherwise.

For a concrete example: let's say you have a List.hpp, List.cpp and main.cpp

In List.hpp you have an abstract class and a regular class that inherits from the abstract class. In main you #include "List.hpp" and not List.cpp, right? So the compiler has NO IDEA what's in that file (until it tries to compile it.) If you don't have the deleted virtual function overridden then the compiler thinks that you're simply trying to instantiate an abstract class and throws an error.

On the other hand, if you're compiling List.cpp, then the compiler will also throw an error, this time complaining that the function you're trying to write has not actually been defined. Because Base::deletedFunction() is different from Derived::deletedFunction().

like image 1
OmnipotentEntity Avatar answered Nov 07 '22 03:11

OmnipotentEntity