Virtual keyword use in C++
Asked Answered
S

5

13

I understand that C++ implements runtime polymorphism thorugh virtual functions and that virtual keyword is inherited but I don't see use of virtual keyword in derived class.

e.g. In below case even if you dropped virtual keyword in derived class still ptr->method() call goes to derived::method. So what extra this virtual keyword is doing in derived class?

#include<iostream>

using namespace std;

class base
{
public:
    virtual void method()
    {
        std::cout << std::endl << "BASE" << std::endl;
    }
};

class derived: public base
{
public:
    virtual void method()
    {
        std::cout << std::endl << "DERIVED" << std::endl;
    }
};

int main()
{
    base* ptr = new derived();
    ptr->method();
    return 9;
}
Slippy answered 7/8, 2013 at 13:4 Comment(4)
As you have seen, it is redundant.Jansson
@Nbr44 wouldn't you make answer from this commentCirilo
virtual is implied in the derived class when overriding a virtual function in the base class. C++11 also introduces the final keyword which prevents further derived classes from reimplementing the virtual function.Sharronsharyl
@Cirilo indeed. I posted it.Stretcher
E
8

Nothing. Just to help remind you what functions are virtual or not.

Emanuel answered 7/8, 2013 at 13:6 Comment(0)
M
22

If the method of the derived class matches a virtual method of one of the base classes by name and signature, and the matched method is virtual, then the method of a derived class becomes virtual as well. So, technically, there is no need to mark such methods as «virtual» in derived classes. However, before C++11 it used to be a good practice just because it is a great hint to those reading the code (it could be hard to keep in mind all of the virtual functions of base class(es)).

Starting with C++11, there are two additional keywords for doing this in the derived classes that help both readability and code robustness. They are «override» and «final». For example, putting «override» in a derived class`s method ensures that a corresponding method of a base class is, in fact, virtual. The «final» keyword does the same plus it prevents the method from being further overriden.

I also wrote about this with more real-world rationales and code examples in my blog, here.

Hope it helps. Good Luck!

Macnamara answered 7/8, 2013 at 13:15 Comment(3)
I've liked your blog post, and I might begin to use override/final in fact.Wynny
The final special identifier does not do the same as override plus..., it only inhibits overriding in derived types. While it makes little sense to make a virtual function final if it does not override another function (why make it virtual then?), the compiler will not verify that it does override anything, for that you need to combine final and override. That is, override requires that there is an override in the base, final implies that there cannot be overrides in derived types. One looks up, the other down. Base test in ideoneExploitation
@DavidRodríguez-dribeas: David, it does except when you also mark that function as «virtual». For example, if you have some function marked just as «final» and there is no virtual base for it, you'll get an error like «only virtual member functions can be marked 'final'»Macnamara
E
8

Nothing. Just to help remind you what functions are virtual or not.

Emanuel answered 7/8, 2013 at 13:6 Comment(0)
S
8

virtual is only necessary in the base class declaration. It's optional in the derived class(es), and probably serves mostly as a reminder in those cases.

C++11 introduces override to make things even more explicit : it explicitely marks a method in a derived class as being an override of a virtual method of a base class.

Stretcher answered 7/8, 2013 at 13:10 Comment(0)
E
0

virtual keyword is optional in drive class because according to the rule when you drive a class with the base class which have virtual function and when you override the virtual function in drive class compiler implicitly assign virtual keyword along with the function. So you not need to explicitly assign the virtual keyword. But this keyword is necessary during multilevel inheritance.

Example:

In your code we add this code.

   class derived: public base {
    public:
        virtual void method() {    // In this line virtual keyword is optional.
              std::cout << std::endl << "DERIVED :: method function" << std::endl;
        }

        virtual void display() {
              std::cout << std::endl << "DERIVED :: display function" << std::endl;
        }
   };

   class deriveChild: public derived {
        public:
            void method() {
                 std::cout << std::endl << "DERIVECHILD :: method" << std::endl;
            }

        void display() {
                 std::cout << std::endl << "DERIVECHILD:: display" << std::endl;
            }
   };

In the main() if you use below code it will give you different output.

   base  *ptr = new deriveChild();
   ptr->method(); // will compile and execute
   ptr->display(); // will generate error because display() is not part of base class.

Now if you want to use display() of deriveChild class then use this code.

   derived *ptr = new deriveChild();
   ptr->method(); // Compile and Execute 
   ptr->display(); // Compile and Execute
Eirene answered 7/8, 2013 at 13:47 Comment(0)
H
0

Implicitly virtual methods in derived classes are virtual in derived classes, no need to explicitly define them virtual.If you declare it will be redundant declaration.

ptr->method();

When the compiler came across the above statement

-> It will try to resolve the above statement, as the method() function is virtual, compiler postpone the resolving of that call to run time.

->As you created the object of derived class at run time, now the compiler will get to know that this method is of derived class.

what extra this virtual keyword is doing in derived class?

Consider this scenario there is one more derived class called Derived2 inherting form derived and it has its own virtual method.

 class derived2: public derived
{
public:
    virtual void method()
    {
        std::cout << std::endl << "DERIVED2" << std::endl;
    }
};

If you call the method() in main like below

int main()
{
    base* ptr = new derived2();
    ptr->method();   //derived2 class method() will get called
    return 9;
}

If the method() in derived2 is not virtual by default, you will end up calling teh derived version of method(), loosing the benefit of runtime polymorphism.

Hence the authors of c++ did a wonderful job here, by making the virtual key word inheritance hierarchical.

Hyperextension answered 7/8, 2013 at 14:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.