C++ virtual keyword for functions in derived classes. Is it necessary?
They are exactly the same. There is no difference between them other than that the first approach requires more typing and is potentially clearer.
Do ALL virtual functions need to be implemented in derived classes?
Derived classes do not have to implement all virtual functions themselves. They only need to implement the pure ones.1 That means the Derived
class in the question is correct. It inherits the bar
implementation from its ancestor class, Abstract
. (This assumes that Abstract::bar
is implemented somewhere. The code in the question declares the method, but doesn't define it. You can define it inline as Trenki's answer shows, or you can define it separately.)
1 And even then, only if the derived class is going to be instantiated. If a derived class is not instantiated directly, but only exists as a base class of more derived classes, then it's those classes that are responsible for having all their pure virtual methods implemented. The "middle" class in the hierarchy is allowed to leave some pure virtual methods unimplemented, just like the base class. If the "middle" class does implement a pure virtual method, then its descendants will inherit that implementation, so they don't have to re-implement it themselves.
Should I use virtual, override, or both keywords?
When you override a function you don't technically need to write either virtual
or override
.
The original base class declaration needs the keyword virtual
to mark it as virtual.
In the derived class the function is virtual by way of having the ¹same type as the base class function.
However, an override
can help avoid bugs by producing a compilation error when the intended override isn't technically an override. For instance, the function type isn't exactly like the base class function. Or that a maintenance of the base class changes that function's type, e.g. adding a defaulted argument.
In the same way, a virtual
keyword in the derived class can make such a bug more subtle by ensuring that the function is still virtual in the further derived classes.
So the general advice is,
Use
virtual
for the base class function declaration.
This is technically necessary.Use
override
(only) for a derived class' override.
This helps maintenance.
Example:
struct Base { virtual void foo() {} };
struct Derived: Base { void foo() override {} };
Notes:
¹ C++ supports covariant raw pointer and raw reference results. With covariance the type of the override isn't exactly the same. It just has a compatible type.
Why do we need virtual functions in C++?
Without "virtual" you get "early binding". Which implementation of the method is used gets decided at compile time based on the type of the pointer that you call through.
With "virtual" you get "late binding". Which implementation of the method is used gets decided at run time based on the type of the pointed-to object - what it was originally constructed as. This is not necessarily what you'd think based on the type of the pointer that points to that object.
class Base
{
public:
void Method1 () { std::cout << "Base::Method1" << std::endl; }
virtual void Method2 () { std::cout << "Base::Method2" << std::endl; }
};
class Derived : public Base
{
public:
void Method1 () { std::cout << "Derived::Method1" << std::endl; }
void Method2 () { std::cout << "Derived::Method2" << std::endl; }
};
Base* basePtr = new Derived ();
// Note - constructed as Derived, but pointer stored as Base*
basePtr->Method1 (); // Prints "Base::Method1"
basePtr->Method2 (); // Prints "Derived::Method2"
EDIT - see this question.
Also - this tutorial covers early and late binding in C++.
Why are virtual functions preferable over derived class objects?
The huge benefit that you get for using the base class pointer type and virtual functions is that you can have one single list that contains several different types of Shape
and you can process them all in a single function where they will all have different behaviors due to their derived types.
As an example, I modified your code by adding the function DrawAllShapes
that takes in a vector<Shapes*>&
. (Be careful of using raw pointers. You really should use vector<std::unique_ptr<Shape>>&
here or something like that.
You have incredible flexibility with this pattern that lets you call the same function on a collection of base class pointer objects but results in different behavior for every object in the collection depending on its derived type.
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
//base class
class Shape {
public:
virtual void draw() = 0; //pure virtual function
};
//derived classes
class Square : public Shape {
public:
void draw() {
cout << "Draw square" << endl;
}
};
class Circle : public Shape {
public:
void draw() {
cout << "Draw circle " << endl;
}
};
void DrawAllShapes(std::vector<Shape*>& shapes) {
for (int i = 0; i < shapes.size(); ++i) {
shapes[i]->draw();
}
}
//////////////////////////////////////////////////////
int main()
{
std::vector<Shape*> shapeVec{ new Square, new Circle, new Square, new Square, new Circle };
DrawAllShapes(shapeVec);
system("pause");
}
Also, imagine if you were using a prebuilt graphical library that already had a Shape class and several shapes defined. What if you wanted to add your own new type of Shape and have it work perfectly with all of the library's functions? All you would have to do is create your own derived class and implement all of the necessary virtual functions exposed by the library's Shape class and then you've literally extended the library beyond its original capabilities.
Using 'virtual' in derived class
virtual
is needed for overrideable functions at the highest (least derived) level. It is optional, but harmless at lower (more derived) levels. It's good for self-documenting the code.
C++ override specifier without virtual? Does override imply virtual?
The answer you're looking for is in https://en.cppreference.com/w/cpp/language/virtual
If some member function vf is declared as virtual in a class Base, and some class Derived, which is derived, directly or indirectly, from Base, has a declaration for member function with the same
name
parameter type list (but not the return type)
cv-qualifiers
ref-qualifiers
Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration) and overrides Base::vf (whether or not the word override is used in its declaration).
Why must I re-declare a virtual function from an inherited class?
It doesn't work this way. You need to declare the methods you're going to define, whether they're overriding a virtual method or not.
This isn't just an unreasonable requirement of the language. Without this you would be unable to define partially virtual class, i.e., you could have BaseSubtype
that has common implementation of method1()
but requires classes derived from it to implement method2()
and method3()
When is the virtual attribute actually needed in a derived class?
For what I've tried, having virtual on a function in the base class automatically makes that function virtual for any descendants.
This is true, the child automatically inherits the virtual
ness of the parent method.
People restate virtual
in child classes as a convention simply to explicitly show that the child intends to override a virtual method (we have override
in C++11 though).
Related Topics
Uninitialized Variable Behaviour in C++
What Happens When I Print an Uninitialized Variable in C++
What Happens to a Detached Thread When Main() Exits
Reading and Writing Binary File
Cmake Error At Cmakelists.Txt:30 (Project): No Cmake_C_Compiler Could Be Found
What Should Go into an .H File
What Is an 'Undeclared Identifier' Error and How to Fix It
Calling Delete on Variable Allocated on the Stack
Returning Unique_Ptr from Functions
What Breaking Changes Are Introduced in C++11
When Should Std::Move Be Used on a Function Return Value
How to Print Unicode Character in C++