How virtual and non-virtual functions are called - c++

using namespace std;
class Foo
{
public:
virtual void foo();
void foo2();
};
class Bar : public Foo
{
public:
void foo();
void foo2();
};
int main()
{
Foo* f = new Foo;
f->foo(); **//1**
f->foo2(); **//2**
return 0;
}
How compiler knows, 1) is dynamic in nature and 2) is static.
How both are internally called.

Collected from here . . .
Non-virtual member functions are resolved statically. That is, the member function is selected statically (at compile-time) based on the type of the pointer (or reference) to the object.
In contrast, virtual member functions are resolved dynamically (at run-time). That is, the member function is selected dynamically (at run-time) based on the type of the object, not the type of the pointer/reference to that object. This is called “dynamic binding.” Most compilers use some variant of the following technique: if the object has one or more virtual functions, the compiler puts a hidden pointer in the object called a “virtual-pointer” or “v-pointer.” This v-pointer points to a global table called the “virtual-table” or “v-table.”
A pure virtual function is a function that must be overridden in a derived class and need not be defined. A virtual function is declared to be “pure” using the curious =0 syntax. For example:
class Base {
public:
void f1(); // not virtual
virtual void f2(); // virtual, not pure
virtual void f3() = 0; // pure virtual
};
Base b; // error: pure virtual f3 not overridden
Here, Base is an abstract class (because it has a pure virtual function), so no objects of class Base can be directly created: Base is (explicitly) meant to be a base class. For example:
class Derived : public Base {
// no f1: fine
// no f2: fine, we inherit Base::f2
void f3();
};
Derived d; // ok: Derived::f3 overrides Base::f3
Example for Virtual or non-Virtual Fenction
#include <iostream>
using namespace std;
class Base {
public:
virtual void NameOf(); // Virtual function.
void InvokingClass(); // Nonvirtual function.
};
// Implement the two functions.
void Base::NameOf() {
cout << "Base::NameOf\n";
}
void Base::InvokingClass() {
cout << "Invoked by Base\n";
}
class Derived : public Base {
public:
void NameOf(); // *Virtual function*.
void InvokingClass(); // *Nonvirtual function.*
};
// Implement the two functions.
void Derived::NameOf() {
cout << "Derived::NameOf\n";
}
void Derived::InvokingClass() {
cout << "Invoked by Derived\n";
}
Main
int main() {
// Declare an object of type Derived.
Derived aDerived;
// Declare two pointers, one of type Derived * and the other
// of type Base *, and initialize them to point to aDerived.
Derived *pDerived = &aDerived;
Base *pBase = &aDerived;
// Call the functions.
pBase->NameOf(); // Call virtual function.
pBase->InvokingClass(); // Call nonvirtual function.
pDerived->NameOf(); // Call virtual function.
pDerived->InvokingClass(); // Call nonvirtual function.
}

In your example both foo() and foo2() will be from the Foo class.
int main()
{
Foo* f = new Foo;
f->foo(); // Foo::foo
f->foo2(); // Foo::foo2
return 0;
}
For you to illustrate the virtual behavior, you need to make an instance of the derived class
int main()
{
Foo* b = new Bar;
b->foo(); // Bar::foo
b->foo2(); // Foo::foo2
static_cast<Bar*>(b)->foo2(); // Bar::foo2
return 0;
}
Notice in the latter case, since b is actually a Bar, it invokes the overriden virtual method foo. But since foo2 isn't declared virtual and b is a Foo, it will invoke Foo::foo2. However, if we cast f to a Bar, it will invoke Bar::foo2

virtual keyword tells compiler for dynamic binding.
To view dynamic binding in action instantiate Foo pointer with Bar object , refer below code.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class Foo
{
public:
virtual void foo(){std::cout<<"Foo foo"<<std::endl;};
void foo2(){std::cout<<"Foo foo2"<<std::endl;};
};
class Bar : public Foo
{
public:
void foo(){std::cout<<"Bar foo"<<std::endl;};
void foo2(){std::cout<<"Bar foo2"<<std::endl;};
};
int main()
{
Foo* f = new Bar;
f->foo();
f->foo2();
return 0;
}

A class which declares or inherits virtual functions has something called a vtable which is used to look up which function to call when you invoke a virtual function. In effect, this table contains pointers to all the virtual functions in the class, something like this (pseudo-code - this may or may not compile):
class Foo {
void foo_impl(){std::cout<<"Foo foo"<<std::endl;}
struct {
void (*foo_ptr)();
} vtable;
public:
Foo(){vtable.foo_ptr = &Foo::foo_impl;}
void foo(){vtable.foo_ptr();}
void foo2(){std::cout<<"Foo foo2"<<std::endl;}
};
class Bar : public Foo {
void foo_impl(){std::cout<<"Bar foo"<<std::endl;}
public:
Bar(){vtable.foo_ptr = &Bar::foo_impl;}
void foo2(){std::cout<<"Bar foo2"<<std::endl;}
};
Thus, when you call a virtual function, the address is first looked up in the vtable, so if you assign a Bar bar; Foo& foo = bar;, then foo.foo() calls Bar's version of foo() instead of Foo's version.

Related

C++: inherited classes have pure virtual functions with identical names. How can I override them separately in my base class?

The following code illustrates my question:
namespace foo1
{
class bar1
{
public:
virtual void fn() = 0; //this must remain pure virtual
};
};
namespace foo2
{
class bar2
{
public:
virtual void fn() = 0; //this must remain pure virtual
};
};
class bar3: public foo1::bar1, public foo2::bar2
{
public:
//can i separately override virtual functions from inherited
//classes that have the same name?
void foo1::bar1::fn() override {std::cout << "bar1";} //error
void foo2::bar2::fn() override {std::cout << "bar2";} //error
};
int main()
{
bar3* obj = new bar3();
((foo1::bar1*)obj)->fn(); //i want this to print "bar1"
((foo2::bar2*)obj)->fn(); //and this to print "bar2"
}
Basically I want to be able to override inherited functions, such that by simply casting my base class object to one of the inherited classes, I can call the different functions even though they have the same name. Is this possible?
Sure.
struct foo1bar1helper:public foo1::bar1{
void fn()final{foo1bar1fn();}
virtual void foo1bar1fn()=0;
};
now bar3 just inherits from this instead of bar1 and overrides foo1bar1fn(),
Do the same with bar2.
You can also use CRTP to dispatch and do away with the extra vtable lookup;
template<class D>
struct foo1bar1helper:public foo1::bar1{
void fn()final{static_cast<D*>(this)->foo1bar1fn();}
};
template<class D>
struct foo2bar2helper:public foo2::bar2{
void fn()final{static_cast<D*>(this)->foo2bar2fn();}
};
class bar3:
public foo1bar1helper<bar3>,
public foo2bar2helper<bar3>
{
public:
void foo1bar1fn(){}
void foo2bar2fn(){}
};
You can not do that. When you do foo1::bar1::fn(), compiler thinks that you are defining function fn of 'bar1' of 'foo1' namespace in class bar3. Hence compiler is throwing below error.
error: cannot define member function ‘foo1::bar1::fn’ within ‘bar3’
But when you extend from an abstract class, you need to give the definition of the function (which should be part of your derived class) in derived class.

Base class method alias

Let's consider the following code:
#include <iostream>
class Base
{
public:
void foo() //Here we have some method called foo.
{
std::cout << "Base::foo()\n";
}
};
class Derived : public Base
{
public:
void foo() //Here we override the Base::foo() with Derived::foo()
{
std::cout << "Derived::foo()\n";
}
};
int main()
{
Base *base1 = new Base;
Derived *der1 = new Derived;
base1->foo(); //Prints "Base::foo()"
der1->foo(); //Prints "Derived::foo()"
}
If I have the above stated classes, I can call the foo method from any of Base or Derived classes instances, depending on what ::foo() I need. But there is some kind of problem: what if I need the Derived class instance, but I do need to call the Base::foo() method from this instance?
The solve of this problem may be next:
I paste the next method to the class Derived
public:
void fooBase()
{
Base::foo();
}
and call Derived::fooBase() when I need Base::foo() method from Derived class instance.
The question is can I do this using using directive with something like this:
using Base::foo=fooBase; //I know this would not compile.
?
der1->Base::foo(); //Prints "Base::foo()"
You can call base class method using scope resolution to specify the function version and resolve the ambiguity which is useful when you don't want to use the default resolution.
Similar (Not exactly same case) example is mentioned # cppreference
struct B { virtual void foo(); };
struct D : B { void foo() override; };
int main()
{
D x;
B& b = x;
b.foo(); // calls D::foo (virtual dispatch)
b.B::foo(); // calls B::foo (static dispatch)
}

Why can't we call virtual function in base class using object of base class in case the virtual function is not overridden in child class?

I have an example code snippet:
class A
{
public:
virtual void func1();
virtual void func2();
};
class B
{
public:
virtual void func2();
virtual void func3();
};
void main()
{
A *obj = new B;
obj->func3();
}
Why does the line obj->func3(); return error?
(we know that a separate virtual table is created for each class)"
Because obj is a pointer to A. A doesn't have func3 on it, so you can't call it.
Note: I've assumed you actually wanted to inherit B from A - it would error before the call, on the assignment in current state.
There's no way this could possibly work. Consider:
Class B : public A
{
void Foo (int);
};
class C : public A
{
void Foo (char);
};
class D : public A
{
void Foo (double);
}
void bar (A* obj)
{
obj->Foo (1); // Uh oh!
}
How can the compiler know what code to generate? Should this pass an integer? A float? A character?
And it's never safe, because the compiler is not able to see the definitions of all the derived classes when it's compiling functions like bar.
If you want to call a function through pointers to a base class, the base class needs to at least define what parameters that function takes.
Your code should look like this if it needs to work. You need to declare the function in base class otherwise in vtable for func3() it space will not be alloted in base class.
class A
{
public:
virtual void func1();
virtual void func2();
virtual void func3(); //virtual function , linking at run time depends on what object it points to
};
class B : public A //public inheritance
{
public:
virtual void func2();
virtual void func3();
};
void main()
{
A *obj = new B; //base class pointer pointing to derived class object
obj->func3(); //since func3() is declared as virtual , dynamic linking takes place and since at
// run times it points to object b , function in class B is invoked
}

Call base class method from derived class object

How can I call a base class method which is overridden by the derived class, from a derived class object?
class Base{
public:
void foo(){cout<<"base";}
};
class Derived:public Base{
public:
void foo(){cout<<"derived";}
}
int main(){
Derived bar;
//call Base::foo() from bar here?
return 0;
}
You can always(*) refer to a base class's function by using a qualified-id:
#include <iostream>
class Base{
public:
void foo(){std::cout<<"base";}
};
class Derived : public Base
{
public:
void foo(){std::cout<<"derived";}
};
int main()
{
Derived bar;
//call Base::foo() from bar here?
bar.Base::foo(); // using a qualified-id
return 0;
}
[Also fixed some typos of the OP.]
(*) Access restrictions still apply, and base classes can be ambiguous.
If Base::foo is not virtual, then Derived::foo does not override Base::foo. Rather, Derived::foo hides Base::foo. The difference can be seen in the following example:
struct Base {
void foo() { std::cout << "Base::foo\n"; }
virtual void bar() { std::cout << "Base::bar\n"; }
};
struct Derived : Base {
void foo() { std::cout << "Derived::foo\n"; }
virtual void bar() { std::cout << "Derived::bar\n"; }
};
int main() {
Derived d;
Base* b = &d;
b->foo(); // calls Base::foo
b->bar(); // calls Derived::bar
}
(Derived::bar is implicitly virtual even if you don't use the virtual keyword, as long as it's signature is compatible to Base::bar.)
A qualified-id is either of the form X :: Y or just :: Y. The part before the :: specifies where we want to look up the identifier Y. In the first form, we look up X, then we look up Y from within X's context. In the second form, we look up Y in the global namespace.
An unqualified-id does not contain a ::, and therefore does not (itself) specify a context where to look up the name.
In an expression b->foo, both b and foo are unqualified-ids. b is looked up in the current context (which in the example above is the main function). We find the local variable Base* b. Because b->foo has the form of a class member access, we look up foo from the context of the type of b (or rather *b). So we look up foo from the context of Base. We will find the member function void foo() declared inside Base, which I'll refer to as Base::foo.
For foo, we're done now, and call Base::foo.
For b->bar, we first find Base::bar, but it is declared virtual. Because it is virtual, we perform a virtual dispatch. This will call the final function overrider in the class hierarchy of the type of the object b points to. Because b points to an object of type Derived, the final overrider is Derived::bar.
When looking up the name foo from Derived's context, we will find Derived::foo. This is why Derived::foo is said to hide Base::foo. Expressions such as d.foo() or, inside a member function of Derived, using simply foo() or this->foo(), will look up from the context of Derived.
When using a qualified-id, we explicitly state the context of where to look up a name. The expression Base::foo states that we want to look up the name foo from the context of Base (it can find functions that Base inherited, for example). Additionally, it disables virtual dispatch.
Therefore, d.Base::foo() will find Base::foo and call it; d.Base::bar() will find Base::bar and call it.
Fun fact: Pure virtual functions can have an implementation. They cannot be called via virtual dispatch, because they need to be overridden. However, you can still call their implementation (if they have one) by using a qualified-id.
#include <iostream>
struct Base {
virtual void foo() = 0;
};
void Base::foo() { std::cout << "look ma, I'm pure virtual!\n"; }
struct Derived : Base {
virtual void foo() { std::cout << "Derived::foo\n"; }
};
int main() {
Derived d;
d.foo(); // calls Derived::foo
d.Base::foo(); // calls Base::foo
}
Note that access-specifiers both of class members and base classes have an influence on whether or not you can use a qualified-id to call a base class's function on an object of a derived type.
For example:
#include <iostream>
struct Base {
public:
void public_fun() { std::cout << "Base::public_fun\n"; }
private:
void private_fun() { std::cout << "Base::private_fun\n"; }
};
struct Public_derived : public Base {
public:
void public_fun() { std::cout << "Public_derived::public_fun\n"; }
void private_fun() { std::cout << "Public_derived::private_fun\n"; }
};
struct Private_derived : private Base {
public:
void public_fun() { std::cout << "Private_derived::public_fun\n"; }
void private_fun() { std::cout << "Private_derived::private_fun\n"; }
};
int main() {
Public_derived p;
p.public_fun(); // allowed, calls Public_derived::public_fun
p.private_fun(); // allowed, calls Public_derived::public_fun
p.Base::public_fun(); // allowed, calls Base::public_fun
p.Base::private_fun(); // NOT allowed, tries to name Base::public_fun
Private_derived r;
r.Base::public_fun(); // NOT allowed, tries to call Base::public_fun
r.Base::private_fun(); // NOT allowed, tries to name Base::private_fun
}
Accessibility is orthogonal to name lookup. So name hiding does not have an influence on it (you can leave out public_fun and private_fun in the derived classes and get the same behaviour and errors for the qualified-id calls).
The error in p.Base::private_fun() is different from the error in r.Base::public_fun() by the way: The first one already fails to refer to the name Base::private_fun (because it's a private name). The second one fails to convert r from Private_derived& to Base& for the this-pointer (essentially). This is why the second one works from within Private_derived or a friend of Private_derived.
First of all Derived should inherit from Base.
class Derived : public Base{
That said
First of you can just not have foo in Derived
class Base{
public:
void foo(){cout<<"base";}
};
class Derived : public Base{
}
int main(){
Derived bar;
bar.foo() // calls Base::foo()
return 0;
}
Second you can make Derived::foo call Base::foo.
class Base{
public:
void foo(){cout<<"base";}
};
class Derived : public Base{
public:
void foo(){ Base::foo(); }
^^^^^^^^^^
}
int main(){
Derived bar;
bar.foo() // calls Base::foo()
return 0;
}
Third you can use qualified id of Base::foo
int main(){
Derived bar;
bar.Base::foo(); // calls Base::foo()
return 0;
}
Consider making foo() virtual in the first place.
class Base {
public:
virtual ~Base() = default;
virtual void foo() { … }
};
class Derived : public Base {
public:
virtual void foo() override { … }
};
However, this does the job:
int main() {
Derived bar;
bar.Base::foo();
return 0;
}
An important [additional] note: you will still have compilation errors if Name Hiding occurs.
In this case, either utilize the using keyword, or use the qualifer. Additionally, see this answer as well.
#include <iostream>
class Base{
public:
void foo(bool bOne, bool bTwo){std::cout<<"base"<<bOne<<bTwo;}
};
class Derived : public Base
{
public:
void foo(bool bOne){std::cout<<"derived"<<bOne;}
};
int main()
{
Derived bar;
//bar.foo(true,true); // error: derived func attempted
bar.foo(true); // no error: derived func
bar.Base::foo(true,true); // no error: base func, qualified
return 0;
}

Why the function from immediate parent is called and not from grandparent class. Is this called function overriding?

class A
{
public:
void test ()
{
cout<<"In A";
}
};
class B :public A
{
public:
void test ()
{
cout<<"In B";
}
};
class C : public B
{
public:
int c;
};
int main()
{
C c;
c.test();
}
The result is: In B...
No, it is not overriding, but rather hiding the original method.
Polymorphic behavior in C++ is restricted to the methods declared virtual, and each implementation of that method in a class hierarchy is called an override of the method.
struct base {
virtual void foo();
void bar();
};
struct derived : base {
virtual void foo();
void bar();
};
In the example base::foo and derived::foo are overrides. When you use a class of type derived through a pointer or reference of type base, the final override method will be called (the lowest one in the hierarchy: in this case derived::foo). The important point here is that the call is through a pointer or reference to base:
void test() {
derived d;
base &b = d;
b.foo(); // derived::foo() <- final overrider
b.bar(); // base::bar() <- non-virtual, no override
d.bar(); // derived::bar() <- hides the method in base
}
What happens in the case of bar (or in your case) is that when the compiler finds the call d.bar() it needs to determine what method to call. To locate the method it will first look inside derived declaration and it will find derived::bar() (which is unrelated to base::bar()) and it will use that method without checking higher in the class hierarchy. If you need to call the method higher in the hierarchy you can do it by either getting a reference to the higher type or fully qualifying the method you want to call.
Note that hiding does not only happen when the signature matches completely, but in all cases where the compiler finds a method with the same name:
struct base {
void bar();
};
struct derived : base {
void bar( int );
};
void test() {
derived d;
base & b;
b.bar(); // ok: base::bar()
d.bar(1); // ok: derived::bar(int)
//b.bar(1); // error: base has no bar method that takes an integer
//d.bar(); // error: derived::bar takes an integer, base::bar is hidden
d.base::bar(); // ok: fully qualifying tells the compiler where to look
}