In Cplusplus, in a derived class, if we define a member function to override a member function in its parent class, do we need to declare the one in the derived class to be virtual?
For example, do we need to declare g to be virtual in B in order for it to override A::g? which one of the following is correct for the above purpose?
class A{
public:
void f(){printf("A");}
virtual void g(){printf("A");}
}
class B : public A{
public:
void f(){printf("B");}
void g(){printf("B");}
}
or
class A{
public:
void f(){printf("A");}
virtual void g(){printf("A");}
}
class B : public A{
public:
void f(){printf("B");}
virtual void g(){printf("B");}
}
Thanks.
Once a method is virtual in a class, its child class has also these virtual class even if you don't add virtual to them.
Adding override is a good habit to avoid subtle error:
class A{
public:
void f() { printf("A"); }
virtual void g() { printf("A"); }
};
class B : public A{
public:
void f() { printf("B"); }
void g() override { printf("B"); }
};
No you don't. The function is virtual from the first point in the hierarchy where you declare it as such.
You can and should specify it as override in c++11 and onward. It specifies explicitly to the compiler that you are trying to override a virtual function in a base class. It than emits an error if you misspell the function name, mistype the parameters or do anything else that can be considered as adding an overload of the function. Prior to c++11, the previous mistakes would silently compile.
Defining member functions virtual in derived classes is optional. You can make the override explicit using C++11's override.
They both do the same thing. You don't need to explicitly say virtual in the derived class, as long as it is virtual in the base class.
In Cplusplus, in a derived class, if we define a member function to override a member function in its parent class, do we need to declare the one in the derived class to be virtual?
From the working draft, [class.virtual]/2 (emphasis mine):
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.
So, no. It is not required.
In pre-C++11 era, declaring virtual also the member functions in the derived classes helped the readers understanding what's going on under the hood.
Since C++11, override is the preferred way, for it not only helps the readers, but also it forces a compile-time check so that typos in the declarations don't introduce subtle errors.
Related
I have a question about using the keyword final in C++. I understand that virtual function is a member function that is declared in the base class, and it is expected to be overridden in the derived classes. By dynamic binding, an appropriate method will be called, depending on the type of the object responsible for the call. However, to prevent a member function in a base class from being overridden in any derived class, we will use the final keyword.
void startEngine() final;// Compile error!
virtual void startEngine() final; //No error
Why we use "final" to PREVENT a member function in the base class from being overridden in derived class meanwhile we still have to use the keyword VIRTUAL (ALLOW to override) together.
I tried to delete the word virtual, but I got a compile error: "nonvirtual function cannot be declared with 'final' modifier"
First at all, we only can stop overriding functions if they can be overridden at all. So final only makes sense on virtual functions at all.
Still, final applied on a single class's virtual function might appear pretty meaningless. But if you consider a more complex hierarchy, matter changes:
class Parent
{
public:
virtual ~Parent() = default;
virtual void f();
};
class Child : public Parent
{
public:
void f() final; // f IS virtual already...
};
class GrandChild : public Child
{
// cannot override f any more – while Child still could!
};
Additionally, consider the following:
class Base
{
public:
virtual ~Base() = default;
void f(); // non-virtual! (i. e. cannot be overridden)
};
class Derived : public Base
{
public:
void f(); // does not override, but HIDEs Base::f!!!
};
Declaring Base::f both virtual and final would prevent hiding as well (but not overloading).
Actually, again this scenario rather makes sense if Base itself already inherited from another polymorphic class. If not and Base is not intended to be inherited, I'd not introduce any virtual functions at all (virtual function calls are more costly than normal function calls!). If then a user still inherits and hides a function – well, his own responsibility...
I know I don't need to declare an overriding function in a subclass as virtual. But if I'm using a virtual function in a sub-subclass do I need to declare the subclass function as virtual?
struct Base
{
virtual int foo();
};
struct Derived : Base
{
virtual int foo() override
{
// ...
}
};
struct DoubleDerived : Derived
{
int foo() override
{
// ...
}
};
You don't have to, the function is virtual anyways, but it makes it unquestionably clear. Previously (before override was available) you could override some function and then if the function was changed in base class your derived class wouldn't override it anymore and the code would compile without any issues. Your function in derived class wouldn't override anything and would become non-virtual.
With override compiler will prevent this kind of mistakes and the function cannot magically become non-virtual if base is changed. In other words, if override or final is used, it's implied that the function is virtual, it would be compilation error otherwise.
I just found Core guideline C.128 that states:
Virtual functions should specify exactly one of virtual, override, or final.
This question already has answers here:
virtual qualifier in derived class
(4 answers)
Closed 7 years ago.
I'm reading about virtual functions and now little confused about overriding virtual functions.
I want to confirm that below given codes are same?
class A{
public:
virtual void fun(){ }
};
class B :public A{
public:
void fun(){}
};
and
class A{
public:
virtual void fun(){ }
};
class B :public A{
public:
virtual void fun(){}
};
If not same then what's the difference? As I expected that B's function with virtual keyword could be same as for B's Derived. Please clear my confusion thanks.
Yes, they are the same. Any function overriding a virtual function in the base class is implicitly declared virtual.
From the last working draft of the c++14 standard:
10.3 Virtual functions [class.virtual]
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref- § 10.3 249 c ISO/IEC N4296 qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides(111) Base::vf.
Emphasis mine
As #Mats and #ixSci pointed out, it is good practice since c++11, to use the keyword override to ensure that you are actually overriding a virtual function and not acidentally overloading a function or overriding a non-virtual function.
Personally, my preferred style is this, but it is up to debate whether the virtual keyword in B adds any value or is even harming readability:
class A{
public:
virtual void fun(){ }
};
class B :public A{
public:
virtual void fun() override {}
};
virtual keyword on the overridden function is completely useless. It doesn't provide anything except readability(some might say it harms readability) but it was the only way in C++03 to convey to the class readers that the function is actually virtual without them checking the base class.
Nowadays it is better to use the keyword which is intruduced specifically for the overriding - override. So your example will look like:
class A{
public:
virtual void fun(){ }
};
class B :public A{
public:
void fun() override{}
};
Not only does it convey the intent but it also makes sure you won't make any mistake when overriding a virtual function.
Virtual keyword tells compiler that there function may be implemented later by inheriting class ( pure virtual). Additionally in c++11 there is keyword override wich checks if implemented method in inheriting class overrodes virtual method of base class. In case of implemented function there is no much difference. We can sam that in case of virtual we talk avout override in other case about hiding of base method ( in both cases your cab still invoke implementation of base). Additionally this is information for programmer that function is intended to override. Additionaly virtual keyword is important in case of destructor. As general rule of thumb if function has some virtual methods it is good to have it a virtual destructor.
Does the virtual qualifier to a virtual function of base class, in the derived class makes any difference ?
class b
{
public:
virtual void foo(){}
};
class d : public b
{
public:
void foo(){ .... }
};
or
class d : public b
{
public:
virtual void foo(){ .... }
};
Is there any difference in these two declarations, apart from that it makes child of d make aware of virtuality of foo() ?
It makes no difference. foo is virtual in all classes that derive from b (and their descendants).
From C++03 standard, §10.3.2:
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name and same parameter list as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.
No difference - it's a virtual override either way.
It's a matter of style and has been definitively discussed here
It's better style to include the virtual keyword. But it's not required.
No difference.
Once foo is virtual, its virtual forever in the class-hierarchy, no matter how far you go from the base in the class-hierarchy.
But I prefer to write virtual even in overrridden functions, because it adds readability to the code, which matters a lot.
Given the base class A and the derived class B:
class A {
public:
virtual void f() = 0;
};
class B : public A {
public:
void g();
};
void B::g() {
cout << "Yay!";
}
void B::f() {
cout << "Argh!";
}
I get errors saying that f() is not declared in B while trying do define void B::f(). Do I have to declare f() explicitly in B? I think that if the interface changes I shouldn't have to correct the declarations in every single class deriving from it. Is there no way for B to get all the virtual functions' declarations from A automatically?
EDIT: I found an article that says the inheritance of pure virtual functions is dependent on the compiler:
http://www.objectmentor.com/resources/articles/abcpvf.pdf
I'm using VC++2008, wonder if there's an option for this.
Do I have to declare f() explicitly in B?
Yes, you have to declare in the class' definition all virtual function of any base classes that you want to override in the class. As for why: That's just the way the C++ syntax is.
Note that the virtual keyword can be omitted for the declaration of overriding virtual functions:
class base {
virtual void f();
virtual void g();
};
class derived : public base {
virtual void f(); // overrides base::f()
void g(); // overrides base::g()
};
Note: A class declaration is this: class my_class;, while this class my_class { /* ... */ }; is a class definition. There's a limited number of things you can do with a class that's only been declared, but not defined. In particular, you cannot create instances of it or call member functions.
For more about the differences between declaration and definitions see here.
Ok, for the benefit of the "declaration vs. definition" debate happening in the comments, here is a quote from the C++03 standard, 3.1/2:
A declaration is a definition unless it [...] is a class name declaration
[...].
3.1/3 then gives a few examples. Amongst them:
[Example: [...]
struct S { int a; int b; }; // defines S, S::a, and S::b
[...]
struct S; // declares S
—end example]
To sum it up: The C++ standard considers struct S; to be a declaration and struct S { /*...*/ }; a definition. I consider this a strong backup of my interpretation of "declaration vs. definition" for classes in C++.
Yes, in C++ you have to explicitly clarify your intention to override the behavior of a base class method by declaring (and defining) it in the derived class. If you try to provide a new implementation in derived class without declaring it in class definition it will be a compiler error.
The C++ class declaration defines the content of the class. If you do not declare f() in B, it looks like you do not override it. B::f() can be implemented only if you declare it.
In your current code, you are just inheriting the function f() in class B and you do not redefine base class's member in derived class.
Is there no way for B to get all the
virtual functions' declarations from A
automatically?
If you do not mark the function f in A as pure virtual with =0, the function is automatically also present in any subclass.
class A {
public:
virtual void f(); // not =0!
};
class B : public A {
public:
void g();
};
void A::f() {
cout << "I am A::f!";
}
void B::g() {
cout << "Yay!";
}
Now:
B* b = new B();
b->f(); // calls A::f
By declaring a pure virtual function you are stating that your class is abstract and that you want to require all concrete derived classes to have an implementation of that function. A derived class which does not supply an implementation for the pure virtual function is an extension of the abstract base class and is, itself, an abstract class. Trying to instantiate an abstract class is, of course, an error.
Pure virtual functions allow you to define an interface "contract" that you expect all derived classes to adhere to. A client of that class can expect that any instantiated class with that interface implements the functions in the contract.
Another interesting tidbit... you may supply a body for a pure virtual function but it is still pure and must be overridden in a concrete derived class. The advantage to supplying the body is to provide base behavior while still forcing derived classes to implement the function. The overridden functions can then call the base function Base::F() just like other virtual functions. When the body is not defined, calling Base::F() on a pure virtual functions is an error.