Overriding vs Virtual
This is the classic question of how polymorphism works I think. The main idea is that you want to abstract the specific type for each object. In other words: You want to be able to call the Child instances without knowing it's a child!
Here is an example:
Assuming you have class "Child" and class "Child2" and "Child3" you want to be able to refer to them through their base class (Parent).
Parent* parents[3];
parents[0] = new Child();
parents[1] = new Child2();
parents[2] = new Child3();
for (int i=0; i<3; ++i)
parents[i]->say();
As you can imagine, this is very powerful. It lets you extend the Parent as many times as you want and functions that take a Parent pointer will still work. For this to work as others mention you need to declare the method as virtual.
The difference between virtual, override, new and sealed override
The virtual keyword is used to modify a method, property, indexer or event declaration, and allow it to be overridden in a derived class. For example, this method can be overridden by any class that inherits it:
Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.
This is all to do with polymorphism. When a virtual method is called on a reference, the actual type of the object that the reference refers to is used to decide which method implementation to use. When a method of a base class is overridden in a derived class, the version in the derived class is used, even if the calling code didn't "know" that the object was an instance of the derived class. For instance:
public class Base
{
public virtual void SomeMethod()
{
}
}
public class Derived : Base
{
public override void SomeMethod()
{
}
}
...
Base d = new Derived();
d.SomeMethod();
will end up calling Derived.SomeMethod if that overrides Base.SomeMethod.
Now, if you use the new keyword instead of override, the method in the derived class doesn't override the method in the base class, it merely hides it. In that case, code like this:
public class Base
{
public virtual void SomeOtherMethod()
{
}
}
public class Derived : Base
{
public new void SomeOtherMethod()
{
}
}
...
Base b = new Derived();
Derived d = new Derived();
b.SomeOtherMethod();
d.SomeOtherMethod();
Will first call Base.SomeOtherMethod , then Derived.SomeOtherMethod . They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.
If you don't specify either new or overrides, the resulting output is the same as if you specified new, but you'll also get a compiler warning (as you may not be aware that you're hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).
An overriding property declaration may include the sealed modifier. Use of this modifier prevents a derived class from further overriding the property. The accessors of a sealed property are also sealed.
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.
c++ virtual keyword vs overriding function
Consider the following example. The important line to illustrate the need for virtual
and override
is c->printMe();
. Note that the type of c
is Base*
, however due to polymorphism it is correctly able to call the overridden method from the derived class. The override
keyword allows the compiler to enforce that a derived class method matches the signature of a base class's method that is marked virtual
. If the override
keyword is added to a derived class function, that function does not also need the virtual
keyword in the derived class as the virtual is implied.
#include <iostream>
class Base{
public:
virtual void printMe(){
std::cout << "I am the base" << std::endl;
}
};
class Derived: public Base{
public:
void printMe() override {
std::cout << "I am the derived" << std::endl;
}
};
int main() {
Base a;
Derived b;
a.printMe();
b.printMe();
Base* c = &b;
c->printMe();
return 0;
}
The output is
I am the base
I am the derived
I am the derived
What are the differences between overriding virtual functions and hiding non-virtual functions?
What is function hiding?
... is a form of name hiding. A simple example:
void foo(int);
namespace X
{
void foo();
void bar()
{
foo(42); // will not find `::foo`
// because `X::foo` hides it
}
}
This also applies to the name lookup in a base class:
class Base
{
public:
void foo(int);
};
class Derived : public Base
{
public:
void foo();
void bar()
{
foo(42); // will not find `Base::foo`
// because `Derived::foo` hides it
}
};
What is function overriding?
This is linked to the concept of virtual functions. [class.virtual]/2
If a virtual member function
vf
is declared in a classBase
and in a classDerived
, derived directly or indirectly fromBase
, a member functionvf
with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) asBase::vf
is declared, thenDerived::vf
is also virtual (whether or not it is so declared) and it overridesBase::vf
.
class Base
{
private:
virtual void vf(int) const &&;
virtual void vf2(int);
virtual Base* vf3(int);
};
class Derived : public Base
{
public: // accessibility doesn't matter!
void vf(int) const &&; // overrides `Base::vf(int) const &&`
void vf2(/*int*/); // does NOT override `Base::vf2`
Derived* vf3(int); // DOES override `Base::vf3` (covariant return type)
};
The final overrider becomes relevant when calling a virtual function: [class.virtual]/2
A virtual member function
C::vf
of a class objectS
is a final overrider unless the most derived class of whichS
is a base class subobject (if any) declares or inherits another member function that overridesvf
.
I.e. if you have an object of type S
, the final overrider is the first overrider you see when traversing the class hierarchy of S
back to its base classes. The important point is that the dynamic type of the function-call expression is used in order to determine the final overrider:
Base* p = new Derived;
p -> vf(42); // dynamic type of `*p` is `Derived`
Base& b = *p;
b . vf(42); // dynamic type of `b` is `Derived`
What is the difference between overriding and hiding?
Essentially, the functions in the base class are always hidden by functions of the same name in a derived class; no matter if the function in the derived class overrides a base class' virtual function or not:
class Base
{
private:
virtual void vf(int);
virtual void vf2(int);
};
class Derived : public Base
{
public:
void vf(); // doesn't override, but hides `Base::vf(int)`
void vf2(int); // overrides and hides `Base::vf2(int)`
};
To find a function name, the static type of an expression is used:
Derived d;
d.vf(42); // `vf` is found as `Derived::vf()`, this call is ill-formed
// (too many arguments)
How do they relate to function overloads?
As "function hiding" is a form of name hiding, all overloads are affected if the name of a function is hidden:
class Base
{
private:
virtual void vf(int);
virtual void vf(double);
};
class Derived : public Base
{
public:
void vf(); // hides `Base::vf(int)` and `Base::vf(double)`
};
For function overriding, only the function in the base class with the same arguments will be overriden; you can of course overload a virtual function:
class Base
{
private:
virtual void vf(int);
virtual void vf(double);
void vf(char); // will be hidden by overrides in a derived class
};
class Derived : public Base
{
public:
void vf(int); // overrides `Base::vf(int)`
void vf(double); // overrides `Base::vf(double)`
};
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).
Are there any subtleties in using both the virtual and override keywords in C++11?
Late to the game, but this C++ Core Guideline seems relevant here:
C.128: Virtual functions should specify exactly one of
virtual
,override
, orfinal
Reason
Readability. Detection of mistakes. Writing explicit
virtual
,override
, orfinal
is self-documenting and enables the compiler to catch mismatch of types and/or names between base and derived classes. However, writing more than one of these three is both redundant and a potential source of errors.It's simple and clear:
virtual
means exactly and only "this is a new virtual function."override
means exactly and only "this is a non-final overrider."final
means exactly and only "this is a final overrider."
C# - Keyword usage virtual+override vs. new
The "new" keyword doesn't override, it signifies a new method that has nothing to do with the base class method.
public class Foo
{
public bool DoSomething() { return false; }
}
public class Bar : Foo
{
public new bool DoSomething() { return true; }
}
public class Test
{
public static void Main ()
{
Foo test = new Bar ();
Console.WriteLine (test.DoSomething ());
}
}
This prints false, if you used override it would have printed true.
(Base code taken from Joseph Daigle)
So, if you are doing real polymorphism you SHOULD ALWAYS OVERRIDE. The only place where you need to use "new" is when the method is not related in any way to the base class version.
Overriding virtual functions and inheritance
Please be patient and read this to get answers to your questions.
Inheritance is a concept in which object of a class inherits the properties and behaviour of object of another class.
Basic Introduction
- Parent class is also called as base class or super class.
- Child class is also called as derived class or subclass.
- An object of a derived class can be referenced through the base class.
For example
#include <iostream>
using namespace std;
class Base {};
class Derived : public Base {};
int main() {
Base *b = new Derived(); // This is completely valid
return 0;
}
Method Overriding in C++
Let's take a basic example
#include <iostream>
using namespace std;
class Base {
public:
void display() { cout << "Base display called\n"; }
};
class Derived : public Base {
public:
void display() { cout << "Derived display called\n"; }
};
int main() {
Base b;
b.display();
Derived d;
d.display();
Base *bptr = &d;
bptr->display();
return 0;
}
Output:
Base display called
Derived display called
Base display called
Now, from the above example you might have guessed that the derived class overrides the base class but this is not the case. The output (3rd line) shows that the base class function is called because the function is not virtual.
Virtual functions in C++
You can make any function of the class virtual by adding the "virtual" keyword at the start of the function.
Lets consider the virtual function example
#include <iostream>
using namespace std;
class Base {
public:
virtual void display() { cout << "Base display called\n"; }
};
class Derived : public Base {
public:
void display() { cout << "Derived display called\n"; }
};
int main() {
Base b;
b.display();
Derived d;
d.display();
Base *bptr = &d;
bptr->display();
return 0;
}
Output:
Base display called
Derived display called
Derived display called
By the above example(line 3 of the output), it is clear that you can achieve method overriding by using the virtual function mechanism in C++.
What is the effect of making a function virtual?
The difference between a normal function and a virtual function is that a normal function is resolved at compile time, also known as static binding, whereas the virtual function is resolved at run time, also known as dynamic binding or late binding. Which method to call (base class display or derived class display method) is resolved at run time since the base class display function is made virtual. You can dive deep into the virtual function mechanism by reading about v-table.
Answers to questions
call(d). I don't quite understand why but it seems that call() can take derived classes of B as an argument.
- A derived class object can be referenced by a base class
But D::g doesn't override B::g and for the reasons I can't understand.
- Because g() is not virtual in base class. Only virtual functions can be overridden. v-table has entries to only virtual functions so that they can be overridden at run time.
call(dd)
- Since f() in DD is a non-const function, therefore f() (non-const f() in DD) is not an overridden method of the parent class D. And since it is being referenced by Base class B, calling b.f() would call the const f() which is being overridden by D. Thus D::f gets printed.
- If f() was a const method in DD then the following would have happened:
When f() gets called, the function is searched first in the base class B,
since f() is virtual, using the v-table pointer, the f() function being overridden in derived class D is resolved. But since f() is not virtual in class D, the overridden f() in DD can't be resolved. Hence D::f gets printed.
But for g(), the base class itself doesn't have virtual g(), so the overridden functions in their derived classes can't be resolved. Hence, B::g get printed.
The above polymorphism has happened because the derived classes were referenced by their base classes(parent classes), but in the last calls, there is no such thing. All the objects are referenced by their respective classes, and hence their appropriate methods are being called.
One basic logic to think about this is that the function is first looked up in the referencing class, and if it is virtual then the function will be searched in derived classes(if the object being referred is a child class). If the derived classes override, then the derived method will be called, else the base method will be called. You can further extend the concept applied to the base class, to the derived class as well like the check whether the function is virtual or not and then if the function is virtual and the object is derived(child of the derived, grandchild of the base) and so on.
Hope this clarifies.
Does final imply override?
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 classB
is marked with the
virt-specifierfinal
and in a classD
derived fromB
a functionD::f
overridesB::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.
Related Topics
Forcing String to Int Function to Consume Entire String
How to Keep My Topmost Window on Top
How to Require an Exact Function Signature in the Detection Idiom
How to Check If Std::Map Contains a Key Without Doing Insert
How to Read/Write Std::String Values From/To Binary Files
Com(C++) Programming Tutorials
How to Use Gpu::Stream in Opencv
Enum Class Constructor C++ , How to Pass Specific Value
Capture _Line_ and _File_ Without #Define
What Happen to Pointers When Vectors Need More Memory and Realocate Memory
Breaking Out from Socket Select
Read Func Interp of a Z3 Array from the Z3 Model
Pointer Comparisons ">" with One Before the First Element of an Array Object
Problems with Scanf("%D\N",&I)