Is it recommended to explicitly make overriding functions virtual?

后端 未结 3 1265
面向向阳花
面向向阳花 2021-01-18 07:46

In times before C++11 when a virtual function was overriden in a derived class, it was recommended to add the virtual keyword also to the derived class function to make the

相关标签:
3条回答
  • 2021-01-18 08:21

    as reported in the documentation for the override keyword, its meaning is that the function at hand MUST override a virtual function:

    In a method declaration, override specifies that the function must be overriding a base class method.

    It is a mean for enforcing (i.e. making the compiler enforce) such requirement. Of course, if the base class' function is not virtual, the code won't compile. Hence, as you pointed out, adding virtual is redundant.

    I would argue that it was not good advice to add it before c++11 either. Consider this snippet of code:

    #include <iostream>
    
    using namespace std;
    
    class A{
        public:
        void f(){
            cout << "A" << endl;
        }
    };
    
    class B : public A{
        public:
        virtual void f(){
            cout << "B" << endl;
        };
    };
    
    class C : public B{
        public:
        void f(){
            cout << "C" << endl;
        };
    };
    
    int main( int argc, char* argv[] ) 
    {
        C c;
        A& aref = c;
        aref.f();
        B& bref = c;
        bref.f();
    }
    

    whose output is, clearly, "A" followed by "C". As you see, adding virtual in class C would have no effect at all, while the virtual in class B plays a key role. Adering to the convention of adding virtual to class C would make this harder to see at a glance.

    0 讨论(0)
  • 2021-01-18 08:23

    Yes, you should prefer to use override instead of virtual when overriding the base class behavior. Because it could lead to possible errors

    How could this possibly lead to errors? Here's an example,

    #include <iostream>
    using namespace std;
    
    class Base {
     public:
        virtual void foo() {
            std::cout << "BASE foo" << std::endl;
        }
        void bar() {
            std::cout << "BASE bar" << std::endl;
        }
    };
    
    
    class A : public Base{
     public:
        void foo() override {
            std::cout << "A foo" << std::endl;
        }
        virtual void bar() { 
            std::cout << "A bar" << std::endl;
        }
    };
    
    class B : public A {
     public:
        void bar() override { 
            std::cout << "B bar" << std::endl;
        }
    };
    
    
    int main(int argc, char *argv[])
    {
        B b;
        A *a = &b;
        Base *base = &b;
        base->foo();
        a->foo();
        base->bar();
        a->bar();
        return 0;
    }
    

    And the output would be

    A foo
    A foo
    BASE bar
    B bar
    

    foo() is overridden correctly but bar isn't and becomes hidden in some cases. The calls to bar() are not invoking the same method even though the underlying object is the same

    If we enforced ourselves to always use override when overriding and virtual only to define new virtual functions then when we try void bar() override {} the compiler complains error: ‘void A::bar()’ marked ‘override’, but does not override

    Which is exactly why the Autosar specification defines the following rule

    Rule A10-3-1 (required, implementation, automated) Virtual function declaration shall contain exactly one of the three specifiers: (1) virtual, (2) override, (3) final.

    Rationale: Specifying more than one of these three specifiers along with virtual function declaration is redundant and a potential source of errors.

    0 讨论(0)
  • 2021-01-18 08:24

    I think this is more a question of taste :-)

    I prefer to only write override behind the definition which implies that the function is already virtual. Programmers are lazy by definition, so keep the source short :-)

    We had add a rule to our coding guidelines where override is a must and the virtual should be removed from old code during normal change process or while refactoring the actual class.

    But this is only our solution and there is no technical reason for this!

    0 讨论(0)
提交回复
热议问题