According to Wikipedia, in this example:
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
virtual void some_func(float) override;
};
I thought override was not a C++ keyword, so what does it really mean?
We can achieve the same thing without that keyword so why would anyone need it?
There is also the keyword final which does not yet work on VS2010 :
struct Base1 final { };
struct Derived1 : Base1 { }; // ill-formed because the class Base1
// has been marked final
In C++11, override and final are "identifiers with special meaning". They are not keywords and only acquire special meaning if used in a specific context (when declaring virtual functions).
The idea is to enable to compiler to catch certain types of errors by allowing the programmer to explicitly state their intent (e.g. to override an existing virtual function rather than create a new one).
Here is the relevant quote from the standard, with examples:
C++11 10.3 4 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. [ Example:
struct B {
virtual void f() const final;
};
struct D : B {
void f() const; // error: D::f attempts to override final B::f
};
—end example ]
5 If a virtual function is marked with the virt-specifier override
and does not override a member function of a base class, the program
is ill-formed. [ Example:
struct B {
virtual void f(int);
};
struct D : B {
void f(long) override; // error: wrong signature overriding B::f
void f(int) override; // OK
};
—end example ]
Related
This question already has an answer here:
method in the derived class got executed without a *virtual* keyword in the referred class
(1 answer)
Closed 2 years ago.
Probably, i misunderstood c++ polymorphism(virtual function).
Please point me what i miss.
the source code is below
#include <iostream>
using namespace std;
class A {
public:
virtual void print(void) {
cout<<"class A"<<endl;
}
};
class B : public A {
public:
void print(void) {
cout<<"class B"<<endl;
}
};
class C : public B {
public:
void print(void) {
cout<<"class C"<<endl;
}
};
int main() {
A a;
B b;
C c;
A *pAa = &a;
A *pAb = &b;
A *pAc = &c;
B *pBc = &c;
pAa->print();
pAb->print();
pAc->print();
pBc->print(); // shouldn't be "class B"
return 0;
}
result
------------------------------
class A
class B
class C
class C // shouldn't be "class B"
my understanding is that
the last print statement should print "class B"
because pBc is a pointer of class B and the print function in class B is non virtual member function. i could not find the answer about this situation.
please tell me why or point me where i can find the answer and
understand c++ polymorphism in comprehension.
thanks.
If a function with a given signature is declared as virtual in a top-level base class, then the function is virtual in all derived classes no matter if it is marked with the keyword virtual (override, final) or not:
virtual function specifier
Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration)
struct Base {
// Pure virtual function.
virtual void foo() const = 0;
};
struct A : public Base {
// Overriding virtual function, even if it
// is not marked as virtual (override, or final).
void foo() const {}
};
In A, adding the virtual specifier to foo() would only bring semantic value; it will be no functional difference whether virtual is omitted or not (unless someone changes the interface in Base).
Many static analyzers enforce(1) marking derived virtual functions with override or final, for two reasons:
semantics; clearly showing the given function is a virtual function (as per being defined so higher up in the inheritance chain), and
enforcement; if a function is marked as override and final but is not actually an overriding function, you will get a compiler error, which can be particularly useful to protect against mistakes when changing a base class interface (whilst forgetting which classes that actually implements this interface).
E.g.:
struct Base {
// Pure virtual function.
virtual void foo() const = 0;
};
struct A : public Base {
// Overriding virtual function.
void foo() const override {}
};
struct B final : public Base {
// Overriding (final) virtual function.
void foo() const final {}
// Error: Function does not override.
// void bar() const override {}
};
(1) E.g. Rule A10-3-1 in the Autsar C++14 Language Guidelines (safety-critical development in automotive) is categorized as a required rule: Virtual function declaration shall contain exactly one of the three specifiers:(1) virtual, (2) override, (3) final.
the print function in class B is non virtual member function
No. Since A::print is marked as virtual and B inherits from A, then B::print is virtual too; regardless of the keywork virtual is specified on it or not.
(emphasis mine)
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).
Suppose I have class A with a virtual function F():
class A
{
virtual void F()
{
// Do something
};
};
And I have another class B which inherits A and redefines F():
class B : A
{
void F()
{
// Do something
};
};
And a different class C which also inherits A but overrides F():
class C : A
{
void F() override
{
// Do something
};
};
What is the difference between F() in classes B and C?
Both are overrides.
When you use the keyword override you ensure a compilation failure if it should happen to not be an override.
And that's good practice.
Both B::f() and C::f() are overrides and they are exactly the same.
override is essentially a compile-time advisory term that will cause a compilation error if the function does not override one in a base class.
This can help program stability: if the name and parameter types to A::f() are changed, then a compile error will result.
I have three classes: B, D and G. D is a B and G is a D. Both B and D are abstract. B is from a third party.
B has a non-pure, virtual method that G needs to implement (to be a D). Can I and is it good practice to redefine/override a virtual function to be pure virtual?
Example:
class B // from a third party
{
public:
virtual void foo();
};
class D : public B
{
public:
void foo() override = 0; // allowed by gcc 4.8.2
virtual void bar() = 0;
};
class G : public D
{
public:
// forgot to reimplement foo
void bar() override;
};
int main()
{
G test; // compiler error is desired
}
To the question of "can I?" gcc allows it, but I do not have the terms/vocabulary to verify the behavior is part of the standard or is undefined and happens to work today.
You asked:
Can I override a virtual function with a pure virtual one?
The answer is: Yes, you can. From the C++11 standard:
10.4 Abstract classes
5 [ Note: An abstract class can be derived from a class that is not abstract, and a pure virtual function may override a virtual function which is not pure. —end note ]
If you compile the code with a more modern compiler then you'll get the following error messages that explain the problem
prog.cc:23:6: error: variable type 'G' is an abstract class
G test; // compiler error is desired
^
prog.cc:10:9: note: unimplemented pure virtual method 'foo' in 'G'
void foo() override = 0; // allowed by gcc 4.8.2
^
1 error generated.
As for the Standard then (10.3 Virtual functions)
11 A virtual function declared in a class shall be defined, or
declared pure (10.4) in that class, or both; but no diagnostic is
required (3.2).
override and final specifier has been introduced in C++11.The below program uses these specifier as follows:
#include<iostream>
template<typename T>
void display(const T& val) { std::cout<<val<<"\n"; }
class Shape {
public:
virtual ~Shape()= default;
virtual void Draw() { display("Shape::Draw()");}
virtual void DisplayName() { display("Shape");}
};
class Circle : public Shape {
public:
virtual ~Circle() = default;
virtual void Draw() override final { display("Circle::Draw()");}
virtual void DisplayName() override { display("Cicle");}
};
int main()
{
}
In the above sample program Circle::Draw() has been defined as override final specifier. This compiles successfully however if the same method is defined as final override, then it throws an compile time error.
Wanted to understand the use cases of override and final specifier for the same method for a class?. When we should use it in our program?
In my opinion it is a compiler bug. At least at www.ideone com the code is compiled successfully.
Acoording to the C++ Standard (10.3 Virtual functions)
4 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.
[ Example:
struct B {
virtual void f() const final;
};
struct D : B {
void f() const; // error: D::f attempts to override final B::f
};
—end example ]
A class may not be a derived class of itself. So the code you showed shall be compiled.
Also
5 If a virtual function is marked with the virt-specifier override and
does not override a member function of a base class, the program is
ill-formed.
[ Example:
struct B {
virtual void f(int);
};
struct D : B {
virtual void f(long) override; // error: wrong signature overriding B::f
virtual void f(int) override; // OK
};
—end example ]
In your example function Draw of class Circle is marked with virt-specidier override and indeed overrides the function of the base class.
This is a compiler bug. According to the grammar that the C++11 standard is specifying in [class.mem]:
member-declarator: declarator
virt-specifier-seqopt pure-specifieropt
declarator
brace-or-equal-initializeropt
identifieropt
attribute-specifier-seqopt : constant-expression
virt-specifier-seq:
virt-specifier
virt-specifier-seq
virt-specifier virt-specifier:
override
final
The virt-specifier-seq doesn't imply any order in the virt-specifiers in the declaration.
When we should use it in our program?
This question might be worth looking at.
It looks like Vlad from Moscow is correct
From the override specifier at cppreference.com:
declarator virt-specifier-seq(optional) function-body
In both cases, virt-specifier-seq, if used, is either override or final, or final override or override final.
And again for the final specifier at cppreference.com:
declarator virt-specifier-seq(optional) function-body
virt-specifier-seq, if used, is either override or final, or final override or override final.
Compiler bugs aside, I would encourage you to pick an order and stick to it consistently - don't mix and match the word order through your codebase.
Wikipedia has the following example on the C++11 final modifier:
struct Base2 {
virtual void f() final;
};
struct Derived2 : Base2 {
void f(); // ill-formed because the virtual function Base2::f has been marked final
};
I don't understand the point of introducing a virtual function and immediately marking it as final. Is this simply a bad example, or is there more to it?
Typically final will not be used on the base class' definition of a virtual function. final will be used by a derived class that overrides the function in order to prevent further derived types from further overriding the function. Since the overriding function must be virtual normally it would mean that anyone could override that function in a further derived type. final allows one to specify a function which overrides another but which cannot be overridden itself.
For example if you're designing a class hierarchy and need to override a function, but you do not want to allow users of the class hierarchy to do the same, then you might mark the functions as final in your derived classes.
Since it's been brought up twice in the comments I want to add:
One reason some give for a base class to declare a non-overriding method to be final is simply so that anyone trying to define that method in a derived class gets an error instead of silently creating a method that 'hides' the base class's method.
struct Base {
void test() { std::cout << "Base::test()\n"; }
};
void run(Base *o) {
o->test();
}
// Some other developer derives a class
struct Derived : Base {
void test() { std::cout << "Derived::test()\n"; }
};
int main() {
Derived o;
o.test();
run(&o);
}
Base's developer doesn't want Derived's developer to do this, and would like it to produce an error. So they write:
struct Base {
virtual void test() final { ... }
};
Using this declaration of Base::foo() causes the definition of Derived to produce an error like:
<source>:14:13: error: declaration of 'test' overrides a 'final' function
void test() { std::cout << "Derived::test()\n"; }
^
<source>:4:22: note: overridden virtual function is here
virtual void test() final { std::cout << "Base::test()\n"; }
^
You can decide if this purpose is worthwhile for yourself, but I want to point out that declaring the function virtual final is not a full solution for preventing this kind of hiding. A derived class can still hide Base::test() without provoking the desired compiler error:
struct Derived : Base {
void test(int = 0) { std::cout << "Derived::test()\n"; }
};
Whether Base::test() is virtual final or not, this definition of Derived is valid and the code Derived o; o.test(); run(&o); behaves exactly the same.
As for clear statements to users, personally I think just not marking a method virtual makes a clearer statement to users that the method is not intended to be overridden than marking it virtual final. But I suppose which way is clearer depends on the developer reading the code and what conventions they are familiar with.
For a function to be labelled final it must be virtual, i.e., in C++11 §10.3 para. 2:
[...] For convenience we say that any virtual function overrides itself.
and para 4:
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. [...]
i.e., final is required to be used with virtual functions (or with classes to block inheritance) only. Thus, the example requires virtual to be used for it to be valid C++ code.
EDIT: To be totally clear: The "point" asked about concerns why virtual is even used. The bottom-line reason why it is used is (i) because the code would not otherwise compile, and, (ii) why make the example more complicated using more classes when one suffices? Thus exactly one class with a virtual final function is used as an example.
It doesn't seem useful at all to me. I think this was just an example to demonstrate the syntax.
One possible use is if you don't want f to really be overrideable, but you still want to generate a vtable, but that is still a horrible way to do things.
Adding to the nice answers above - Here is a well-known application of final (very much inspired from Java). Assume we define a function wait() in a Base class, and we want only one implementation of wait() in all its descendants. In this case, we can declare wait() as final.
For example:
class Base {
public:
virtual void wait() final { cout << "I m inside Base::wait()" << endl; }
void wait_non_final() { cout << "I m inside Base::wait_non_final()" << endl; }
};
and here is the definition of the derived class:
class Derived : public Base {
public:
// assume programmer had no idea there is a function Base::wait()
// error: wait is final
void wait() { cout << "I am inside Derived::wait() \n"; }
// that's ok
void wait_non_final() { cout << "I am inside Derived::wait_non_final(); }
}
It would be useless (and not correct) if wait() was a pure virtual function. In this case: the compiler will ask you to define wait() inside the derived class. If you do so, it will give you an error because wait() is final.
Why should a final function be virtual? (which is also confusing) Because (imo) 1) the concept of final is very close to the concept of virtual functions [virtual functions has many implementations - final functions has only one implementation], 2) it is easy to implement the final effect using vtables.
I don't understand the point of introducing a virtual function and immediately marking it as final.
The purpose of that example is to illustrate how final works, and it does just that.
A practical purpose might be to see how a vtable influences a class' size.
struct Base2 {
virtual void f() final;
};
struct Base1 {
};
assert(sizeof(Base2) != sizeof(Base1)); //probably
Base2 can simply be used to test platform specifics, and there's no point in overriding f() since it's there just for testing purposes, so it's marked final. Of course, if you're doing this, there's something wrong in the design. I personally wouldn't create a class with a virtual function just to check the size of the vfptr.
While refactoring legacy code (e.g. removing a method that is virtual from a mother class), this is useful to ensure none of the child classes are using this virtual function.
// Removing foo method is not impacting any child class => this compiles
struct NoImpact { virtual void foo() final {} };
struct OK : NoImpact {};
// Removing foo method is impacting a child class => NOK class does not compile
struct ImpactChildClass { virtual void foo() final {} };
struct NOK : ImpactChildClass { void foo() {} };
int main() {}
Here is why you might actually choose to declare a function both virtual and final in a base class:
class A {
void f();
};
class B : public A {
void f(); // Compiles fine!
};
class C {
virtual void f() final;
};
class D : public C {
void f(); // Generates error.
};
A function marked final has to be also be virtual. Marking a function final prevents you from declaring a function with the same name and signature in a derived class.
Instead of this:
public:
virtual void f();
I find it useful to write this:
public:
virtual void f() final
{
do_f(); // breakpoint here
}
protected:
virtual void do_f();
The main reason being that you now have a single place to breakpoint before dispatching into any of potentially many overridden implementations. Sadly (IMHO), saying "final" also requires that you say "virtual."
I found another case where for virtual function is useful to be declared as final. This case is part of SonarQube list of warnings. The warning description says:
Calling an overridable member function from a constructor or destructor could result in unexpected behavior when instantiating a subclass which overrides the member function.
For example:
- By contract, the subclass class constructor starts by calling the parent class constructor.
- The parent class constructor calls the parent member function and not the one overridden in the child class, which is confusing for child class' developer.
- It can produce an undefined behavior if the member function is pure virtual in the parent class.
Noncompliant Code Example
class Parent {
public:
Parent() {
method1();
method2(); // Noncompliant; confusing because Parent::method2() will always been called even if the method is overridden
}
virtual ~Parent() {
method3(); // Noncompliant; undefined behavior (ex: throws a "pure virtual method called" exception)
}
protected:
void method1() { /*...*/ }
virtual void method2() { /*...*/ }
virtual void method3() = 0; // pure virtual
};
class Child : public Parent {
public:
Child() { // leads to a call to Parent::method2(), not Child::method2()
}
virtual ~Child() {
method3(); // Noncompliant; Child::method3() will always be called even if a child class overrides method3
}
protected:
void method2() override { /*...*/ }
void method3() override { /*...*/ }
};
Compliant Solution
class Parent {
public:
Parent() {
method1();
Parent::method2(); // acceptable but poor design
}
virtual ~Parent() {
// call to pure virtual function removed
}
protected:
void method1() { /*...*/ }
virtual void method2() { /*...*/ }
virtual void method3() = 0;
};
class Child : public Parent {
public:
Child() {
}
virtual ~Child() {
method3(); // method3() is now final so this is okay
}
protected:
void method2() override { /*...*/ }
void method3() final { /*...*/ } // this virtual function is "final"
};
virtual + final are used in one function declaration for making the example short.
Regarding the syntax of virtual and final, the Wikipedia example would be more expressive by introducing struct Base2 : Base1 with Base1 containing virtual void f(); and Base2 containing void f() final; (see below).
Standard
Referring to N3690:
virtual as function-specifier can be part of decl-specifier-seq
final can be part of virt-specifier-seq
There is no rule having to use the keyword virtual and the Identifiers with special meaning final together. Sec 8.4, function definitions (heed opt = optional):
function-definition:
attribute-specifier-seq(opt) decl-specifier-seq(opt) declarator virt-specifier-seq(opt) function-body
Practice
With C++11, you can omit the virtual keyword when using final. This compiles on gcc >4.7.1, on clang >3.0 with C++11, on msvc, ... (see compiler explorer).
struct A
{
virtual void f() {}
};
struct B : A
{
void f() final {}
};
int main()
{
auto b = B();
b.f();
}
PS: The example on cppreference also does not use virtual together with final in the same declaration.
PPS: The same applies for override.
I think most of the answers miss an important point. final means no more override after it has been specified. Marking it on a base class is close to pointless indeed.
When a derived class might get derived further, it can use final to lock the implementation of a given method to the one it provided.
#include <iostream>
class A {
public:
virtual void foo() = 0;
virtual void bar() = 0;
};
class B : public A {
public:
void foo() final override { std::cout<<"B::foo()"<<std::endl; }
void bar() override { std::cout<<"B::bar()"<<std::endl; }
};
class C : public B {
public:
// can't do this as B marked ::foo final!
// void foo() override { std::cout<<"C::foo()"<<std::endl; }
void bar() override { std::cout<<"C::bar()"<<std::endl; }
};