As I understand it, the override keyword states that a given declaration implements a base virtual method, and the compilation should fail if there is no matching base method found.
My understanding of the final keyword is that it tells the compiler that no class shall override this virtual function.
So is override final redundant? It seems to compile fine. What information does override final convey that final does not? What is the use case for such a combination?
final does not require the function to override anything in the first place. Its effect is defined in [class.virtual]/4 as
If a virtual function f in some class B is marked with the
virt-specifier final and in a class D derived from B a function D::f
overrides B::f, the program is ill-formed.
That's it. Now override final would simply mean
„This function overrides a base class one (override) and cannot be overriden itself (final).“
final on it's own would impose a weaker requirement.
override and final have independent behavior.
Note that final can only be used for virtual functions though - [class.mem]/8
A virt-specifier-seq shall appear only in the declaration of a
virtual member function (10.3).
Hence the declaration
void foo() final;
Is effectively the same as
virtual void foo() final override;
Since both require foo to override something - the second declaration by using override, and the first one by being valid if and only if foo is implicitly virtual, i.e. when foo is overriding a virtual function called foo in a base class, which makes foo in the derived one automatically virtual. Thus override would be superfluous in declarations where final, but not virtual, occurs.
Still, the latter declaration expresses the intent a lot clearer and should definitely be preferred.
final does not necessarily imply that the function is overridden. It's perfectly valid (if of somewhat dubious value) to declare a virtual function as final on its first declaration in the inheritance hierarchy.
One reason I can think of to create a virtual and immediately final function is if you want to prevent a derived class from giving the same name & parameters a different meaning.
(Skip to the end to see the conclusion if you're in a hurry.)
Both override and final can appear only in declaration in a virtual function. And both key words can be used in the same function declaration, but whether it is useful to use them both depends on situations.
Take the following code as an example:
#include <iostream>
using std::cout; using std::endl;
struct B {
virtual void f1() { cout << "B::f1() "; }
virtual void f2() { cout << "B::f2() "; }
virtual void f3() { cout << "B::f3() "; }
virtual void f6() final { cout << "B::f6() "; }
void f7() { cout << "B::f7() "; }
void f8() { cout << "B::f8() "; }
void f9() { cout << "B::f9() "; }
};
struct D : B {
void f1() override { cout << "D::f1() "; }
void f2() final { cout << "D::f2() "; }
void f3() override final { cout << "D::f3() "; } // need not have override
// should have override, otherwise add new virtual function
virtual void f4() final { cout << "D::f4() "; }
//virtual void f5() override final; // Error, no virtual function in base class
//void f6(); // Error, override a final virtual function
void f7() { cout << "D::f7() "; }
virtual void f8() { cout << "D::f8() "; }
//void f9() override; // Error, override a nonvirtual function
};
int main() {
B b; D d;
B *bp = &b, *bd = &d; D *dp = &d;
bp->f1(); bp->f2(); bp->f3(); bp->f6(); bp->f7(); bp->f8(); bp->f9(); cout << endl;
bd->f1(); bd->f2(); bd->f3(); bd->f6(); bd->f7(); bd->f8(); bd->f9(); cout << endl;
dp->f1(); dp->f2(); dp->f3(); dp->f6(); dp->f7(); dp->f8(); dp->f9(); cout << endl;
return 0;
}
The output is
B::f1() B::f2() B::f3() B::f6() B::f7() B::f8() B::f9()
D::f1() D::f2() D::f3() B::f6() B::f7() B::f8() B::f9()
D::f1() D::f2() D::f3() B::f6() D::f7() D::f8() B::f9()
Compare f1() and f6(). We know that override and final is indepent sematically.
override means the function is overriding a virtual function in its base class. See f1() and f3().
final means the function cannot be overrided by its derived class. (But the function itself need not override a base class virtual function.) See f6() and f4().
Compare f2() and f3(). We know that if a member function is declared without virtual and with final, it means that it already override a virtual function in base class. In this case, the key word override is redundant.
Compare f4() and f5(). We know that if a member function is declared with virtualand if it is not the first virtual function in inheritance hierarchy, then we should use override to specify the override relationship. Otherwise, we may accidentally add new virtual function in derived class.
Compare f1() and f7(). We know that any member function, not just virtual ones, can be overridden in derived class. What virtual specifies is polymorphism, which means the decision as to which function to run is delayed until run time instead of compile time. (This should be avoid in practice.)
Compare f7() and f8(). We know that we can even override a base class function and make it a new virtual one. (Which means any member function f8() of class derived from D will be virtual.) (This should be avoid in practice too.)
Compare f7() and f9(). We know that override can help us find the error when we want to override a virtual function in derived class while forgot to add key word virtual in base class.
In conclusion, the best practice in my own view is:
only use virtual in declaration of the first virtual function in base class;
always use override to specify override virtual function in derived class, unless final is also specified.
The following code (with the final specifier) compiles. But compilation fails when final is replaced with override final. Thus override final conveys more information (and prevents compilation) than just final.
class Base
{
public:
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual void foo() final
{
std::cout << "in Derived foo\n";
}
};
Essentially, override final says this method cannot be overridden in any derived class and this method overrides a virtual method in a base class. final alone doesn't specify the base class overriding part.
No final does not necessarily imply override. In fact, you could declare a virtual function that you immediately declare final see here. The final keyword simply states that no derived class can create an override of this function.
The override keyword is important in that it enforces that you are indeed actually overriding a virtual function (instead of declaring a new unrelated one). See this post regarding override
So long story short, they each serve their own particular purpose, and it is often correct to use both.
Related
I got a Question in my Exam which was this:
Function Overriding means the functions have the same prototype but
differ in their body
Justify the Statement with the help of an Example.
Now I quoted this code snippet as Example :
#include<iostream>
using namespace std;
class A {
public: virtual void print() {
cout << "I am Base Class's print Function" << endl;
}
};
class B: public A {
public: void print() {
cout << "I am Derived's Class print function" << endl;
}
};
Here I have made two classes, Class A and Class B and Class B is inheriting Class A. Now, by definition of Method Overriding, we mean that the Function which gets created in the Base Class gets overridden in the Derived Class.
I made the Function in the Base Class as a Virtual Function.
Now, my main() file:
int main() {
A * a1;
B b1;
a1 = & b1;
a1 - > print();
}
Now, I want to ask that is my above code snippet example for above question is right or not. I have performed Function Overriding at run time. In my main file, the Base Class Object is a Pointer that is having the Address of the Derived Class. When I will call print() function using a1, it will execute the print() function of the Derived Class.
So isn't my example justified? Am I right or not?
You could use the classical Cat vs Dog example where both classes inherit from a common base class, i.e. Animal. The common base class can then have a pure virtual function that is then overridden with a differing implementation (method body) in each subclass.
#include <iostream>
class Animal
{
public:
virtual ~Animal() = default;
virtual void MakeSound() const = 0;
};
class Dog : public Animal
{
public:
virtual void MakeSound() const override;
};
class Cat : public Animal
{
public:
virtual void MakeSound() const override;
};
void Dog::MakeSound() const
{
std::cout << "Woof!" << std::endl;
}
void Cat::MakeSound() const
{
std::cout << "Meow!" << std::endl;
}
int main()
{
const Dog dog{};
const Cat cat{};
const Animal& firstAnimal{dog};
const Animal& secondAnimal{cat};
/*
* These functions have the same prototype, void MakeSound(),
* but differ in their implementation.
*/
firstAnimal.MakeSound();
secondAnimal.MakeSound();
return 0;
}
If you teacher expected this as answer and considers your example as wrong then I would argue that they teach you overriding the wrong way.
From cppreference:
Virtual functions are member functions whose behavior can be overridden in derived classes.
Of course this does not strictly imply the reverse statement: "functions that can be overriden are virtual". But if this wasnt true, the quoted sentence would make little sense.
Non-virtual methods are not really meant to be overriden. From the C++ FAQ:
Should a derived class redefine (“override”) a member function that is non-virtual in a base class?
It’s legal, but it ain’t moral. [...]
Note that they put "override" in quotes, because strictly speaking it is not overriding but merely redefining.
Further, you can read on cpprefernce about the override specifier (emphasize mine):
In a member function declaration or definition, override ensures that the function is virtual and is overriding a virtual function from a base class. The program is ill-formed (a compile-time error is generated) if this is not true.
TL;DR If I had to judge I would consider this as a misleading bad example for overriding, while your code seems fine. It could benefit from using override and A should have a virtual destructor, but thats details.
Considering this code example:
#include <iostream>
using namespace std;
class Base
{
private:
int number;
public:
Base():number(10){}
~Base(){}
virtual void print()
{
cout << "Base class" << endl;
}
};
class Derived : public Base
{
public:
Derived():Base(){}
~Derived(){}
void print(int value)
{
//printing number in Base class and paramter value
cout << "Derived with value " << value << " number is" << number << endl;
}
};
I wanted to use polymorphism and call theoverloaded print() function.
So use these classes as follows:
void somewhere_else()
{
Base* polymorphism = new Derived();
polymorphism->print(5); //Error indicating there are too many parameter
//thinking that I am trying to use print in Base class
((Derived*)polymorphism)->print(5)
//This works as I am casting the variable as Derived variable
}
Unfortunately, I can't call print() from the base class pointer (compilation error, see comment above). I can only call it with a cast.
Is there a better way to keep the polymorphism and still calls overloaded function based on derived class?
In your code you have two different member functions, that have different signatures:
a virtual print() that takes no argument. It is declared and defined in Base, and inherited in Derived
a non-virtual print() that takes one int argument. It is declared and defined ONLY for Derived
So the base object doesn't know a print function with an int parameter. This is why you need to cast (which is by the way a symptom that should ring alarm bells if you need it).
How to improve ?
First, if you want to override a virtual function in a derived class, use the keyword override:
class Derived : public Base
{
public:
Derived():Base(){}
~Derived(){}
void print(int value) override
{
...
}
};
This will ensure an error message in case of subtle mismatch in the function signature:
prog.cpp:23:10: error: ‘void Derived::print(int)’ marked ‘override’, but does not override
void print(int value) override
^~~~~
Then make sure that the signatures are aligned in the base class and derived class (i.e. either both take an int argument or non of them.
Note that you can't access a private member of the base class in a derived class. You have to define number as protected to print it in Derived.
Finally, if you have a base class having a virtual member, it is a sound practice to systematically make the destructor virtual. This will avoid subtle bugs for more complex classes:
class Base
{
protected:
int number;
public:
Base():number(10){}
virtual ~Base(){}
virtual void print(int value)
{
...
}
};
Here the online demo
Now that the things are working, here a short article making the difference between overload and override.
I'm looking at some C++ example code, which effectively has the following:
class Foo : public mynamespace::Bar
{
public:
Foo()
{
// Do some stuff
}
void Delta() override
{
// Do some stuff
Bar::Delta();
}
};
I am having trouble understanding why the line Bar::Delta(); exists. Given that class Foo inherits class Bar, then surely when Foo::Delta() is called, this overrides anything existing in Bar::Delta(), and hence this line is redundant.
Or am I misunderstanding this whole inheritance thing? Maybe override doesn't override everything?
Bar::Delta();
is a function call. Isn't that what it looks like?
It's calling the base class version of Delta - by explicitly qualifying it as Bar::Delta - in addition to whatever extra stuff Foo's version does.
Maybe override doesn't override everything?
The override keyword just asks the compiler to verify you're really overriding a virtual function - otherwise, it's easy to accidentally write a new function which doesn't override anything (eg. because a parameter type is slightly different, or one version is const-qualified, or you changed the base class and forgot to update the derived class, or ...).
Here you are overriding the virtual function. That doesn't stop the base class implementation from existing, and as you've seen you can still call it.
You can (and should) test your intuition about this sort of thing yourself. Consider the trivial test code below. What do you think it will do?
Now actually run it. Were you right? If not, which part was unexpected?
#include <iostream>
using namespace std;
struct Bar {
virtual void Delta() {
cout << "Bar::Delta\n";
}
};
struct Foo : public Bar {
void Delta() override
{
cout << "Foo::Delta\n";
Bar::Delta();
}
};
int main()
{
cout << "b.Delta()\n";
Bar b;
b.Delta();
cout << "f.Delta()\n";
Foo f;
f.Delta();
cout << "pb->Delta()\n";
Bar *pb = &b;
pb->Delta();
cout << "pb->Delta()\n";
pb = &f;
pb->Delta();
}
This is a common pattern. In fact, the :: syntax for calling an overridden member function is there specifically for this situation.
It is very common for member function in a base class to perform some computation or action which can be done independently of the derived class, and let the derived class do things specific to the derivation.
Here is a fictitious example:
class Stock {
protected:
double totalDividend;
double baseDividend;
double adjustmentFactor;
public:
Stock(double d, double a)
: baseDividend(d), totalDividend(d), adjustmentFactor(a) {
}
virtual void double ComputeDividend() {
return totalDividend * adjustmentFactor;
}
};
class SpecialStock {
private:
double specialDividend;
public:
SpecialStock(double d, double sd, double a)
: Stock(d, a), specialDividend(sd) {
}
virtual void double ComputeDividend() override {
// Do some preparations
totalDividend = baseDividend + specialDividend;
// Call the overridden function from the base class
return Stock::ComputeDividend();
}
};
You seem to misunderstand what override means in c++. You should not really bother by it for your case. It's like a normal virtual function. override keyword is just a safety mechanism to ensure that a base class has matching function. It doesn't change anything other than semantic compile-time checks.
It is somewhat useful to guard against typical mismatches, such a const vs non-const versions, etc.
The virtual method mechanism does not replace the original member functions. It still is there in the Derived object. What happens is that a level of indirection is introduced, so a call to base.foo() uses a function pointer to call correct implementation which is Derived::Foo() in your case. But Base::Foo() still exists, and this is the syntax to "access" it. You can look up how exactly it work by searching materials on virtual methods.
Maybe override doesn't override everything?
The override specifier can be used to make compile-time checks when overriding a function that the function being overridden is virtual and is in fact being overridden.
why the line Bar::Delta(); exists
This line calls the base Delta function which might have some useful tasks to perform even though you have overridden it.
A simple example:
class Base
{
public:
virtual ~Base() {}
virtual void Foo()
{
// run tasks that are common to all derived types
}
};
class Derived : public Base
{
public:
void Foo() override
{
Base::Foo(); // we have to call this explicitly
// run tasks specific to the derived type
}
};
Delta in foo is a virtual method which "does some stuff" and then calls the base class's implementation of Delta.
override does not override anything, declaring the method as virtual does that. override is just for the compiler to throw syntax error in case the parent class doesn't have the Delta method.
I have those objects:
class A{
public:
void print();
}
class B : public A{
public:
void print();
}
class C : public A{
public:
void print();
}
The function print:
void A::print(){
cout << "A" << endl;
}
void B::print(){
cout << "B" << endl;
}
void C::print(){
cout << "C" << endl;
}
Now I have a vector of A objects which can contain A B or C
for(unsigned int i = 0; i<m_vA.size(); i++)
{
cout << m_vA[i]->print() << endl;
}
But each time the function returns A even if this is a B or C object
Thanks for the help
You do not override the function. To do so, use "virtual" keyword while declaring this function in A class.
You forgot to make the member function virtual.
The short answer is: use virtual as the other answers indicate, so that you override the function, instead of hiding it.
Here's an excerpt from Herb Sutter's Exceptional C++ - Item 21: Overriding Virtual Functions which explains in more detail what is going on with your code:
It's important to differentiate between three common terms:
To overload a function f() means to provide another function with the same name f() in the same scope but with different
parameter types. When f() is actually called, the compiler will try
to pick the best match based on the actual parameters that are
supplied.
To override a virtual function f() means to provide another function with the same name f() and the same parameter types in a
derived class.
To hide a function f() in an enclosing scope (base class, outer class, or namespace) means to provide another function with the same
name f() in an inner scope (derived class, nested class, or
namespace), which will hide the same function name in an enclosing
scope.
Because your various print functions are in nested scopes, and because you have not provided the virtual keyword, each function is hiding the functions of the same name in the base class(es):
class A{
public:
void print();
}
class B : public A{
public:
void print(); // Hides A::print()
}
class C : public A{
public:
void print(); // Hides A::print() and B::print()
}
So, when the compiler performs name resolution, it will look within the current scope (which is the class definition for the type from which you have called the function) and it will stop there because it will find a non-virtual function with the name print.
Polymorphism requires the use of the virtual keyword to declare that the method should be stored in a virtual table (vtable), and its implementation looked-up at runtime.
Note also that your class definitions need semicolons after the closing brackets.
class A
{
public:
virtual void print()
{
cout << "A" << endl;
}
};
class B : public A
{
public:
virtual void print() override
{
cout << "B" << endl;
}
};
class C : public A
{
public:
virtual void print() override
{
cout << "C" << endl;
}
};
On a side note, the virtual keyword in the derived classes is not necessary (it's implicitly added in derived classes if the base class function is declared virtual), but good to use for readability and to avoid potential issues with the odd compiler that requires it. The override identifier is also not necessary, but forces the compiler to check that you are in fact overriding a virtual function that exists in the superclass. (I think override is only available in C++11).
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;
}
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!
Nothing. Just to help remind you what functions are virtual or not.
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.
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.
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