non virtual method call in a virtual method, C++ - c++

Here is the code I'm talking about
#include <stdio.h>
#include <stdlib.h>
class A {
public:
void method() {printf("method A\n");}
virtual void parentMethod() { printf("parentMethod\n"); method(); }
};
class B : public A {
public:
void method() {printf("method B\n");}
};
int main(void) {
A a;
B b;
a.parentMethod();
b.parentMethod();
}
My question is why this is happening? Why when b.parentMethod() is called it doesn't print method B. I realize that it has something to do with method() being in A and B as well as being non-virtual, but I can't get my head around it. Would someone be able to explain this behaviour?
Any help is appreciated.

You code was missing a virtual keyword:
#include <stdio.h>
#include <stdlib.h>
class A {
public:
virtual void method() {printf("method A\n");} // virtual was missing
void parentMethod() { printf("parentMethod\n"); method(); } // unnecessary virtual keyword
};
class B : public A {
public:
void method() {printf("method B\n");}
};
int main(void) {
A a;
B b;
a.parentMethod();
b.parentMethod();
}
The definition in the most upper class must contain the virtual keyword. It is very logical if you think about it. In this case, when you call method() the compiler knows it has to do something more than with a normal function call immediately.
Otherwise, it would have to find and iterate on all the derived types to see if they contain a redefinition of method().

My question is why this is happening? Why when b.parentMethod() is called it doesn't print method B. I realize that it has something to
do with method() being in A and B as well as being non-virtual, but I
can't get my head around it. Would someone be able to explain this
behaviour?
C++ has two levels of indirection when it comes to classes/structures. You have your "plain functions" (including "overloaded", "lambdas", static, etc.) and you have your "virtual functions". First, let's explain "plain functions".
struct Foo {
void goo();
};
In this structure, goo is just a plain old functions. If you try to write it in C, this would be analogous to calling,
void goo(struct Foo *this);
Nothing magical, just a plain function with a "hidden" pointer (all c++ functions have that "hidden" this pointer passed to them). Now, let's re-implement this function in an inherited structure,
struct Goo : public Foo {
void goo();
};
...
Goo g;
g.goo();
Foo f;
f.goo();
Here, plain as day, g.goo() calls goo() in Goo structure, and f.goo() calls goo() in Foo structure. So, in C functions, this would be just,
void goo(struct Foo *this);
void goo(struct Goo *this);
provided C did parameter overloading. But still, just plain functions. Calling goo() in Foo object will call different function than calling goo() in Goo object. Compile time resolution only. But now, let's make our function "virtual"
struct Foo {
virtual void goo();
};
struct Goo : public Foo {
void goo(); // <- also virtual because Foo::goo() is virtual
// In C++11 you'll want to write
// void goo() override;
// which verifies that you spelled function name correctly
// and are not making *new* virtual functions! common error!!
};
...
Goo g;
g.goo();
Foo f;
f.goo();
What happens here is that Foo now contains a "virtual table". The compiler now creates a table of functions that maps location of "latest" goo() function. Namely, implicit Foo() constructor would do something like,
virt_table[goo_function_idx] = &Foo::goo;
and then the constructor in Goo() would update this table with,
virt_table[goo_function_idx] = &Goo::goo;
And then when you have,
Foo *f = new Goo();
f->goo();
what happens is akin to,
f->virt_table[goo_function_idx]();
The function location is looked up in the "virtual table", and that function is called. This means runtime resolution of functions, or polymorphism. And this is how Goo::goo() is called.
Without this table, the compiler can only call functions it knows for said object. So in your example, b.parentMethod() is looked up in the table and called. But method() is not part of that table, so only compile-time resolution is attempted. And since this pointer is A*, you get A::method called.
I hope this clears up the "virtual table" business - it's literally an internal lookup table, but only for functions marked as virtual!
PS. You may ask, "but the this pointer will get 'upcast' by the virtual table from Foo* to Goo*", and yes, it would. I'll leave it as an exercise for you to figure out why that would always be correct.

Well you are correct. This is happening because your method is not virtual. When you are calling it through the parent class, there is no way for it to know, that it was overloaded, so A::method is always called. If you mark method as virtual, then call to it will be routed through the class vtable, so A::method would be replaced by the B::method in the ascendant class.

virtual means that a method can be overridden in a subclass. I think you wanted method, not parentMethod, to be overridden for B. I've renamed parentMethod to foo to be less misleading.
#include <stdio.h>
#include <stdlib.h>
class A {
public:
virtual void method() {printf("method A\n");}
void foo() { printf("foo\n"); method(); }
};
class B : public A {
public:
void method() {printf("method B\n");}
};
int main(void) {
A a;
B b;
a.foo();
b.foo();
}
You'll see that this gives the expected output:
foo
method A
foo
method B
Here's the ideone.

Related

How to defined a static interface in base class and make sure the interface must be implement in derived class?

It is very easy that we can make sure derived class must implement interface defined in base class.
That is pure virtual function.
For example:
class BaseClass
{
...
virtual void print()=0;
...
}
class DerivedClass :public BaseClass
{
// function must be implement, otherwise compiler will complain ...
void print()
{
}
};
Can we defined a static interface in base class and make sure the interface must be implement in derivate class?
I want something like this
class BaseClass
{
...
static void print(); // base class only define static interface
...
}
class DerivedClass :public BaseClass
{
// derived class must implement interface, otherwise compiler will complain ...
static void print()
{
}
};
I have no idea about this.
Thanks for your time.
It is not possible to make a virtual static function. For the simple reason that when calling a static function, you always know the class that defines that function in compile time. Unlike virtual functions, where you don't know the type of the object whose method you're calling.
For example:
class A
{
public:
virtual void f() {printf("A");}
};
class B : public A
{
virtual void f() override {printf("B");}
};
void g(A& a)
{
a.f();
}
int main()
{
B b;
g(b);
return 0;
}
In the above example, inside the function g, the correct function is invoked (B::f). Even though while compiling the function it is not known what the type of its argument is (it could be A or any class derived from A).
Without making f() virtual, you would have overloaded the method f, rather than overridden it. Which means that in the following example, the output would be "A", even though you might expect it to be "B":
class A
{
public:
void f() {printf("A");}
};
class B : public A
{
void f() {printf("B");}
};
void g(A& a)
{
a.f();
}
int main()
{
B b;
g(b);
return 0;
}
This may cause serious bugs, and it is suggested to never overload base class methods, and to always use the override keyword when overriding a virtual method to escape those bugs.
When making a static function, you can simply overload it, it would not create a compilation error. However, you probably never should overload it, because it may hide a bug that is very difficult to track (you are certain that B::f() is being called while actually A::f() is being called).
Furthermore, it is not possible to 'force' the derived class to implement a static interface, because there is no such thing as a static interface. Because you have no virtual static functions, you may not pass a reference or pointer to the interface that would implement this function.

Explicitly stop late binding

If we create an object pointer to base class class which points to its child class object then we use virtual key word for late binding
So.,in case of late binding,, our code goes like this :-
#include<iostream>
using namespace std;
struct A{
virtual void print() {
cout<<"function1";
}
};
struct B : public A{
void print(){
cout<<"function2";
}
};
struct C : public B{
void print(){
cout<<"function3";
}
};
int main(){
A* a = new C();
A* p = new B();
a->print();
p->print();
}
Now my question is : when we use virtual keyword in base class, all the functions of derived classes created in base class will become virtual.
In multilevel inheritance, is there any way so that we can stop the function of class c from being virtual??
Any way to break this chain of virtual functions ?
Sorry for any mistakes in question but i tried my best.. ☺️☺️
It is not possible to make a function that is already virtual be not virtual in a child class.
Virtuality is a property of the top-level base class, not the child classes. Once a method has been marked as virtual, and pointer to that class must use dynamic dispatch for that function when calling because the pointer could be pointing to a child class that has overridden the behaviour.
Consider this code:
A a;
B b;
C c;
A * ap = &a;
A * bp = &b;
A * cp = &c;
ap->print(); // 'function1'
bp->print(); // 'function2'
cp->print(); // 'function3'
Here, the calls to print cannot tell which function to call at compile time, they absolutely must use dynamic dispatch.
However, you can make C::print behave like A::print
struct C : public B {
void print() {
A::print();
}
};
Which results in:
ap->print(); // 'function1'
bp->print(); // 'function2'
cp->print(); // 'function1'
And if the behaviour of A::print() changes, C::print() mirrors those changes.
This will still be overridable though, unless you use the final keyword as outlined below.
Original answer:
I believe you are looking for the final specifier.
It's only available as of C++11 though.
To quote en.cppreference's page about the final specifier:
When used in a virtual function declaration or definition, final
ensures that the function is virtual and specifies that it may not be
overridden by derived classes. The program is ill-formed (a
compile-time error is generated) otherwise.
And a variation of the example they give, demonstrating the solution to your problem:
struct A
{
virtual void foo();
};
struct B : A
{
void foo() final; // B::foo is overridden and it is the final override
};
struct C : B
{
void foo() override; // Error: foo cannot be overridden as it's final in B
};

Function overriding in C++ works without 'virtual'

I have a class that contains some functions (none are virtual) and 2 more classes publicly inherit that class. In both the sub classes I override the same function of the base class.
After creating objects of all three classes in main (located at the same file), I call the original function with the baseclass object and the overridden functions with the derivedclass objects.
I was expecting all 3 function calls to run the original function from the base class (since I didn't use 'virtual' anywhere in the code), but I actually get each version of that function working according to the class in which it was defined (3 different versions).
I have the classes Base & Derived as follows:
struct Base
{
void foo();
};
struct Derived : Base
{
void foo();
};
in main:
int main()
{
Derived d;
d.foo();
}
I thought d.foo() should run Base::foo() if not using 'virtual'.
This is not "overriding"... and it doesn't need to be.
struct Base
{
void foo();
};
struct Derived : Base
{
void foo();
};
int main()
{
Derived d;
d.foo();
}
If I understand you correctly, then you were expecting this to execute Base::foo(), because the functions are not virtual and therefore one does not override the other.
But, here, you do not need virtual dispatch: the rules of inheritance simply state that you'll get the right function for the type of the object you run it on.
When you need virtual dispatch/overriding is a slightly different case: it's when you use indirection:
int main()
{
Base* ptr = new Derived();
ptr->foo();
delete ptr;
}
In the above snippet, the result will be that Base::foo() is called, because the expression ptr->foo() doesn't know that *ptr is really a Derived. All it knows is that ptr is a Base*.
This is where adding virtual (and, in doing so, making the one function override the other) makes magic happen.
You cannot override something that isn't virtual. Non-virtual member functions are dispatched statically based on the type of the instance object.
You could cheat by "overriding" a function by making it an inline function calling something indirectly. Something like (in C++03)
class Foo;
typedef int foo_sig_t (Foo&, std::string&);
class Foo {
foo_sig_t *funptr;
public:
int do_fun(std::string&s) { return funptr(*this,s); }
Foo (foo_sig_t* fun): funptr(fun) {};
~Foo () { funptr= NULL; };
// etc
};
class Bar : public Foo {
static int barfun(Bar&, std::string& s) {
std::cout << s << std::endl;
return (int) s.size();
};
public:
Bar () : Foo(reinterpret_cast<foo_sig_t*>)(&barfun)) {};
// etc...
};
and later:
Bar b;
int x=b.do_fun("hello");
Officially this is not overloading a virtual function, but it looks very close to one. However, in my above Foo example each Foo instance has its own funptr, which is not necessarily shared by a class. But all Bar instances share the same funptr pointing to the same barfun.
BTW, using C++11 lambda anonymous functions (internally implemented as closures), that would be simpler and shorter.
Of course, virtual functions are in generally in fact implemented by a similar mechanism: objects (with some virtual stuff) implicitly start with a hidden field (perhaps "named" _vptr) giving the vtable (or virtual method table).

What's the point of a final virtual function?

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; }
};

C++ member function virtual override and overload at the same time

If I have a code like this:
struct A {
virtual void f(int) {}
virtual void f(void*) {}
};
struct B : public A {
void f(int) {}
};
struct C : public B {
void f(void*) {}
};
int main() {
C c;
c.f(1);
return 0;
}
I get an error that says that I am trying to do an invalid conversion from int to void*. Why can't compiler figure out that he has to call B::f, since both functions are declared as virtual?
After reading jalf's answer I went and reduced it even further. This one does not work as well. Not very intuitive.
struct A {
virtual void f(int) {}
};
struct B : public A {
void f(void*) {}
};
int main() {
B b;
b.f(1);
return 0;
}
The short answer is "because that's how overload resolution works in C++".
The compiler searches for functions F inside the C class, and if it finds any, it stops the search, and tries to pick a candidate among those. It only looks inside base classes if no matching functions were found in the derived class.
However, you can explicitly introduce the base class functions into the derived class' namespace:
struct C : public B {
void f(void*) {}
using B::f; // Add B's f function to C's namespace, allowing it to participate in overload resolution
};
Or you could do this:
void main()
{
A *a = new C();
a->f(1); //This will call f(int) from B(Polymorphism)
}
Well I think first of all you did not understand what virtual mechanism or polymorhism. When the polymorphism is achieved only by using object pointers. I think you are new to c++. Without using object pointers then there is no meaning of polymorphism or virtual keyword use base class pointer and assign the desired derived class objects to it. Then call and try it.