Difference between virtual and non virtual function for child class [duplicate] - c++

This question already has answers here:
Virtual function keyword
(2 answers)
Closed 8 years ago.
Let my parent class be;
class parent {
virtual void printx () { cout<< "parent" ; }
}
Case 1:
class child : public parent {
virtual void printx() { cout<< " child" ; }
}
Case 2:
class child : public parent {
void printx() { cout<< " child" ; }
}
Is there any difference if I omit virtual in the child class for the function printx in case 2?

Provided the function signatures are the same, the child class is not required to add the virtual to the method, the compiler will take care of this for you. If a function is declared virtual in a parent class, the child's overridden methods are also virtual.
If C++11 is available, consider adding the override specifier to the overridden method in the child class;
class child : public parent {
void printx() override { cout<< " child" ; }
}
With the override, the compiler will check to make sure that this method does indeed override a virtual method in the base class. If it does not, the compiler will generate an error for you. For example; as in the original posting, it will pick up the spelling difference between printx and pritnx.

Both are same. If a function is declared as virtual in base class then it would be virtual in all derived classes whether you explicitly mention it or not.

Related

Calling the overriding function through a reference of base class [duplicate]

This question already has answers here:
Difference between calling of virtual function and non virtual function?
(5 answers)
Virtual dispatch implementation details
(3 answers)
Closed 8 months ago.
I googled and learnt the differences between function hiding and function overriding.
I mean I understand the output of testStuff(), which is seen in the below code snippet.
But what confuses me is that a instance of derived class could be assigned to a reference of the base class. And calling the overriding function through the said reference finally invoking the function of the derived class other than the base class.
Could somebody shed some light on this matter?
Here is the code snippet:
#include <iostream>
using namespace std;
class Parent {
public:
void doA() { cout << "doA in Parent" << endl; }
virtual void doB() { cout << "doB in Parent" << endl; }
};
class Child : public Parent {
public:
void doA() { cout << "doA in Child" << endl; }
void doB() { cout << "doB in Child" << endl; }
};
void testStuff() { //I can understand this function well.
Parent* p1 = new Parent();
Parent* p2 = new Child();
Child* cp = new Child();
p1->doA();
p2->doA();
cp->doA();
p1->doB();
p2->doB();
cp->doB();
}
int main()
{
Child cld;
Parent prt = cld;
Parent &ref_prt = cld;
prt.doA();
ref_prt.doA();
prt.doB();
ref_prt.doB(); //The one which most surprised me! I know `Child::doB()` overrides `Parent::doB()`. And I understand the output for `testStuff()`.
//But I still do not understand this line and `Parent &ref_prt=cld`.
return 0;
}
Here is the output:
doA in Parent
doA in Parent
doB in Parent
doB in Child
But what confuses me is that a instance of derived class could be assigned to a reference of the base class. And calling the overriding function through the said reference finally invoking the function of the derived class other than the base class.
It is indeed exactly like that.
If a member function is virtual in a class, then calling it through a pointer-or-reference to that class will result in a dynamic dispatch, so if the actual object is of a derived class which overrides that function (btw, it neededn't declare it virtual because it's already virtual; and it'd better delcare it override, so that it errors out if it doesn't really override, e.g. because you mistyped the name), than that override will be called.
Tha page linked above should sufficient to shed light on this as well as other doubts.

C++ Virtual Void vs no virtual [duplicate]

This question already has answers here:
Why do we need virtual functions in C++?
(27 answers)
Overriding non-virtual methods
(3 answers)
Closed 4 years ago.
I'm confused about virtual functions. I was told that virtual in parent class means I can override it in child class. However if I omit the virtual in parent class, I'm still able to override it.
#include <iostream>
using namespace std;
class Enemy{
public:
//if I remove virtual, it still gets overriden in child class
virtual void attack(){
cout << "Attack Enemy!" << endl;
}
};
class Minion : public Enemy {
public:
void attack(){
cout << "Attack Minon!" << endl;
}
};
int main() {
Minion m;
m.attack();
}
If a function is virtual, the call is dynamically dispatched to the implementation provided by the derived type through the vtable at runtime, whereas without, the compiler looks at the object at compile time and selects the class-method of the static type. If you have a pointer to the base-class this means that the base-implementation is used, if the function is not virtual:
Enemy *e = new Minion(); e->attack();
will print "Attack Enemy!" if attack is not virtual. When using a virtual function, the compiler will insert some logic to lookup the right implementation at run-time, and, when e->attack() gets executed, look up the implementation in the vtable of the object pointer to by e, finding that Minion overrides attack, and thus printing "Attack Minion!".
If you want to force your derived classes to override the base-class method you can also make the function purely virtual by using
virtual void attack() = 0;
You can override the method in question and ideally declare that with the override keyword to allow the compiler to complain when you aren't overriding anything.
class Enemy {
public:
virtual ~Enemy() = default; /* Don't forget... or non-virtual protected. */
virtual void attack() {}
};
class Minion : public Enemy {
public:
void attack() override {}
};
Your confusion probably stems from the fact that you can equally well shadow the base class method.
class Enemy {
public:
virtual ~Enemy() = default;
void attack() {}
};
class Minion : public Enemy {
public:
void attack() {}
};
This does not only do something different, it would in addition be an example for extraordinarily poor naming, as it's confusing to the reader: Equal member function names with identical signatures in the context of a class hierarchy are inevitably associated with overridden methods.
You haven't overriden it, you have simply added another method with the same signature.
Enemy* enemy = new Minion();
enemy->attack();
delete enemy;
If this calls the code from Minion you did it right. If it calls the code from Enemy, you did something wrong. You will need virtual to do it right.

Overriding private functions

I am working on a class (call it class D) that is derived from a class (call it class B) and will be inherited by another class (call it class E). I want instances of class E to have access to all the public functions of its parents but I specifically want to prevent class E from overriding any of the virtual functions in parent classes.
I thought by overriding the function in the private part of class D it would prevent the derived classes from overriding, but that appears not to be the case. This compiles and runs the function in class E:
#include <iostream>
//an abstract base class
class b
{
public:
virtual ~b() = default;
protected:
virtual void print() = 0;
virtual void print_two()
{
std::cout << "base class" << std::endl;
}
};
class d: public b
{
public:
virtual ~d() = default;
private:
void print() override // note this is not virtual -adding final here does the trick
{
std::cout << "class d" << std::endl;
}
using b::print_two; //this doesn't work either
};
class e : public d
{
public:
void print() override //why is this possible given the function it's overriding is private and non-virtual?
{
std::cout << "class e" << std::endl;
}
void print_two() override //why is this possible given the function it's overriding is private and non-virtual?
{
std::cout << "print two class e" << std::endl;
}
};
int main()
{
e foo;
foo.print();
foo.print_two();
}
So two questions out of this:
Why can I override a function that is virtual in a grandparent but not virtual in a parent?
Why can I override a function that is protected in a grandparent but private in a parent?
I tried it in g++ and clang and it compiles with no errors or warnings (-Wall -Wextra -Wpedantic)
Why can I override a function that is virtual in a grandparent but not virtual in a parent?
There's no such thing. Once a function is declared virtual, it's implicitly virtual in all derived classes. Only way to come close to "unvirtualize" a member function is to declare it final. That would make it impossible to override it further, but it will still be subject to dynamic dispatch when called via an ancestor reference/pointer. Any access via the child that declared it final or its decedents, could be resolved statically, however.
Why can I override a function that is protected in a grandparent but private in a parent?
Access specifiers don't affect a name's visibility. They only affect where that name can be used. Defining the same function will override the parent's implementation and be called by dynamic dispatch. Again, because this is not something that falls under the realms of "access" to the name.
The child can't refer to the parent's implementation (Parent::foo) if it's private in the parent, and neither can outside code that consumes the interface. It ensure the function is only ever called in a controlled manner. Very useful for testing pre and post conditions.

Does final imply override?

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.

C++ Class and virtual method

I am having two problem about virtual methods.
First:
class Parent
{
public:
virtual void SHOW(int x = 5) { cout << "PARENT " << x << endl; }
};
class Child : public Parent
{
public:
virtual void SHOW(int y = 10) { cout << "CHILD " << y << endl; }
};
int main()
{
Child Y;
Parent* P = &Y;
P->SHOW();
getch();
return 0;
}
I think tt should be CHILD 10 but the result is CHILD 5
And another:
class Parent
{
public:
virtual void SHOW() { cout << "PARENT" << endl; }
};
class Child : public Parent
{
private:
virtual void SHOW() { cout << "CHILD" << endl; }
};
int main()
{
Child Y;
Parent* P = &Y;
P->SHOW();
getch();
return 0;
}
It'll show CHILD on the screen. I don't know how a private method which was called from outside?
Thank you. I'm learning English so.. :)
1)
C++ Standard says
A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides.
§8.3.6/10
2)
Overriding public virtual functions with private functions in C++
A virtual function call uses the default arguments in the declaration of the virtual function determined by the static type of the pointer you use to call the function. In your case the static type of P is Parent although the dynamic type resolves to Child. This is according to C++ standard.
This is a good example of why it is typically best to make virtual functions private and public functions non-virtual. Herb Sutter once called this the Non-Virtual Interface Idiom (NVI).
Let's apply it to your code. I'll also change the function name "SHOW" to "show", because all-uppercase in C++ usually denotes a macro. Furthermore, I'll add a virtual destructor, because newbies are reading these questions and they shouldn't see a polymorphic class without one. Note that destructors are an exception to NVI.
Here we go:
class Parent
{
public:
void show(int x = 5) { doShow(x); }
virtual ~Parent() {}
private:
virtual void doShow(int x) { cout << "PARENT " << x << endl; }
};
class Child : public Parent
{
private:
virtual void doShow(int x) { cout << "CHILD " << x << endl; }
};
Default arguments are usually useful for code which uses the objects of a class. That code then uses the public functions.
Parent *p = new Child;
p->show(); // here's where a default argument is a useful feature
delete p;
Inheriting classes, however, are interested in something completely different, namely in the virtual functions of the base class. It turns out that you rarely feel the need for default arguments when you write the code for a subclass.
Bottom line:
Default arguments and virtual functions shouldn't be mixed. There is an item for this in the famous Effective C++ book by Scott Meyers: "Never redefine an inherited default parameter value". You should read that book.
Using NVI, you will typically not have this problem anyway, because it turns out default arguments are more of a thing for public functions, and with NVI, public functions aren't virtual.