19 March 2012

C++11: overriding virtual functions


C++03 and older versions allow one to change the prototype (declaration) of a virtual function in a derived class, thus, introducing a new function instead of overriding that in the base class, e.g.:

class Base_
{
public:
       virtual void func(char)
       {
              std::cout << "Base_::func(char)" << std::endl;
       }
};

class Derived_ : public Base_
{
public:
       virtual void func(double)
       {
              std::cout << "Derived_::func(double)" << std::endl;
       }
};

int main()
{
       Base_ *d1 = new Derived_;
       d1->func(1);

       return 0;
}

The output of the program is “Base_::func(char)”, which is certainly not the one we wanted.
To exclude such cases of accidental errors, C++11 provides a new specifier - override, which makes the compiler check that the virtual function in derived class properly overrides that in the base class. The specifier should be added to the virtual function header in derived class:

class Derived_ : public Base_
{
public:
       virtual void func(double) override
       {
              std::cout << "Derived_::func(double)" << std::endl;
       }
};

Now the compiler will complain for incorrect overriding. Also, override will make the compiler complain if there is not a virtual function with same name in the base class, e.g.:

class Derived_ : public Base_
{
public:
       virtual void func2(const std::string&) override
       {
              std::cout << "Derived_::func2" << std::endl;
       }
};

Another keyword is called final. Specifying the virtual function as final, makes the compiler verify that the function is not overridden in any of the derived classes. So compiling the following piece of code will bring to an error:

class Base_
{
public:
       virtual void func(char) final
       {
              std::cout << "Base_::func(char)" << std::endl;
       }
};

class Derived_ : public Base_
{
public:
       virtual void func(char)
       {
              std::cout << "Derived_::func(char)" << std::endl;
       }
};

Remember that override is used with the functions of derived classes, and final - with those of base class. The keyword final has one more usage; any class can be declared final thus prohibiting inheritance from that class. For more details on this, please see my post named “Prohibiting inheritance”.