class Base
{
public:
int a;
virtual void fun1()
{
cout<<"Hello Base"<<endl;
}
void fun2()
{
fun1();
}
};
class Derived: public Base
{
int a;
void fun1()
{
cout<<"Hello Derived"<<endl;
}
};
int main()
{
Base * B = new Derived;
B->fun2();
return 1;
}
Please help me understand why output is Hello Derived.How this function binding takes place.How is virtual table entry created for Base and derived class.
The virtual table is created when the class objects are constructed. When you construct a Derived object, it will first call the Base constructor (which creates the vtable and writes its own Base::fun1 into that. Then the Derived constructor runs and overwrites the vtable entry for fun1 with its own implementation (Derived::fun1).
If you then, at any later point (even from within any Base function) call fun1 of such an object instance, it will look into the vtable and call whatever function it finds there. As explained above, it is Derived::fun1 that is in the vtable of a Derived object after construction, so this is the one that will get called. It doesn't matter that you are currently in a Base function, the vtable entry does not change.
Note that during construction, the vtable is not fully set up: If you were to call fun1 from within the Base constructor, you would not call Derived::fun1 but Base::fun1 because Derived did not replace the vtable entries yet.
Also note that fully specifying the function (e.g. calling Base::fun1() on a Derived instance) will not do a vtable lookup but instead use exactly the specified function.
The pseudo code looks like this:
#include <iostream>
class Base{
protected:
void **vt_ptr;
public:
int a;
//Executed prior to base member initialization
//and reexecuted prior to Base destructor call
void set_dynamic_type(){
vt_ptr = Base::vtable;
}
/*virtual*/
void fun1(){
reinterpret_cast<void(*)(Base&)>(vt_ptr[1])(*this);
}
void fun2(){
fun1();
}
private:
static void func1_def(Base& pseudo_obj_arg){
Base* this=&pseudo_obj_arg;
std::cout<<"Hello Base"<<std::endl;
}
static void* vtable[2];
};
void* Base::vtable[2]={
reinterpret_cast<void*>(&type_id_of_Base),
reinterpret_cast<void*>(&Base::func1_def)};
class Derived: public Base
{
int a;
//Executed after Base intialization,
//before Derived member initialization.
//Reexecuted prior to Derived destructor call
void set_dynamic_type(){
Base::vt_ptr = Derived::vtable;
}
private:
static void func1_def(Base& pseudo_obj_arg){
Derived* this=static_cast<Derived*>(&pseudo_obj_arg);
std::cout<<"Hello Derived"<<std::endl;
}
static void* vtable[2];
};
void* Derived::vtable[2]={
reinterpret_cast<void*>(&type_id_of_Derived),
reinterpret_cast<void*>(&Derived::func1_def)};
Also a qualified call as in: obj.Base::func1() directly calls Base::func1_def(obj), otherwise it goes throw the devirtualization process described in Base::func1.
Related
I have a class A as a base class of class B.
I have called the non-virtual function, abc(), within my virtual function, xyz(), as mentioned below.
Due to run-time polymorphism, B:xyz is called – I understand this.
However, I don't understand, why was it followed by B:abc and not A:abc, as abc is a non-virtual function.
Please note: I have come across the following question: Virtual function calling a non-virtual function. It mentions that calling abc() within the virtual function is equivalent to this->abc(), hence the output. However, I am not sure I understand this part.
Because, when I do the opposite (i.e. a non-virtual function calling a virtual function), that time correct run time polymorphism is displayed. What happens to the this pointer then?
//Virtual function calling non-virtual
class A
{
public:
void abc()
{
cout<<"A:abc"<<endl;
}
virtual void xyz()
{
cout<<"A:xyz"<<endl;
abc();
}
};
class B: public A
{
public:
void abc()
{
cout<<"B:abc"<<endl;
}
void xyz()
{
cout<<"B:xyz"<<endl;
abc();
}
};
int main() {
A *obj3 = new B;
obj3->xyz();\
return 0;
}
Output
B:xyz
B:abc
//Non-virtual calling virtual function
#include <iostream>
using namespace std;
class A
{
public:
void abc()
{
cout<<"A:abc"<<endl;
xyz();
}
virtual void xyz()
{
cout<<"A:xyz"<<endl;
}
};
class B: public A
{
public:
void abc()
{
cout<<"B:abc"<<endl;
xyz();
}
void xyz()
{
cout<<"B:xyz"<<endl;
}
};
int main() {
A *obj3 = new B;
obj3->abc();
return 0;
}
Output
A:abc
B:xyz
Calls to your non-virtual abc function are resolved, effectively, at compile time: so, when that is called from within another member function of class B, the class B version of the function is called, and is passed a pointer (this) to the object from which it is being called; similarly, if called from within a class A function, then the class A definition will be used. That is to say, to the compiler, non-virtual functions associate with a class, rather than any particular instance of the class.
However, your virtual xyz function is handled differently by the compiler; in this case, a reference or pointer to the function is added to the class definition (this is generally added into what is known as a vtable, although the details are implementation-specific); when any objects of your class(es) are created, they include a copy of that function pointer and/or vtable. When the compiler sees code to call such a virtual function, it translates that into a call via the appropriate function pointer; so, the function 'travels with' the actual object: whether the function is called from the derived class or base class (in your code) is irrelevant – the function called is the one belonging to the object (instance) from which it is invoked.
In summary: calls to non-virtual functions are resolved at compile time, whereas calls to virtual functions are (conceptually) resolved at run time.
To see creation of this "vtable" in action, try compiling and running the following code:
#include <iostream>
class A {
public:
int i;
~A() = default;
void foo() { std::cout << i << std::endl; }
};
class B {
public:
int i;
virtual ~B() = default;
virtual void foo() { std::cout << i << std::endl; }
};
int main()
{
std::cout << sizeof(A) << std::endl;
std::cout << sizeof(B) << std::endl;
return 0;
}
The only difference between the two classes is that one has virtual functions and the other doesn't – yet that causes a significant difference in the size of class objects: the size of the vtable (with, possibly, some 'padding' for optimal alingment of data)! (On my 64-bit Windows, using MSVC, I get sizes of 4 and 16, but the actual values will vary between compilers and platforms.)
class Base {
public:
virtual void f();
void f(int);
virtual ~Base();
};
class Derived : public Base {
public:
void f();
};
int main()
{
Derived *ptr = new Derived;
ptr->f(1);
delete ptr;
return 0;
}
ptr->f(1); is showing the following error: "too many arguments in function call".
Why is this isn't possible? isn't derived inherited all the functions form base and is free to use any of them?
I could call it explicitly and it would work but why isn't this allowed?
What you are seeing is called hiding.
When you override the function void f() in the Derived class, you hide all other variants of the f function in the Base class.
You can solve this with the using keyword:
class Derived : public Base {
public:
using Base::f; // Pull all `f` symbols from the base class into the scope of this class
void f() override; // Override the non-argument version
};
As mentioned by #Some Programming Dude : it is because of Hiding.
To understand hiding in relatively simpler language
Inheritance is meant to bring Baseclass variables / functions in Derived class.
But, on 1 condition : "If its not already available in Derived Class"
Since f() is already available in Derived, it doesn't make sense to look at Base class from compiler perspective.
That's the precise reason why you need to scope clarify while calling this function
void main()
{
Derived *ptr = new Derived;
ptr->Base::f(1);
delete ptr;
}
Suppose for time being that Derived do have the access to the function void Base::f(int);. Then it will be a case of function overloading. But, this is invalid case of function overloading since one function f(int);is in Base and other function f(); is in Derived. Function Overloading happens inside a single class. Function Overriding happens across classes. The example you posted is a case of Name Hiding in Inheritance
"Derived *ptr" This definition will only allow "ptr" to access all the member functions which are defined via Derived class or its child class. But, it will not allow u to access the member functions which are coming in Derived class because of inheritance.
If u want to access base class version of function "f" then use "Base *ptr" and it will choose the correct version of function automatically as shown :)
class Base {
public:
virtual void f()
{
cout<<"Here 2"<<endl;
}
void f(int x)
{
cout<<"Here 1"<<endl;
}
virtual ~Base() {}
};
class Derived : public Base {
public:
void f()
{
cout<<"Here 3"<<endl;
}
virtual ~Derived() {}
};
int main()
{
Base *ptr = new Derived;
ptr->f(1);
delete ptr;
return 0;
}
output is
Here 1
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).
I'm slightly confused about runtime polymorphism. Correct me if I am wrong, but to my knowledge, runtime polymorphism means that function definitions will get resolved at runtime.
Take this example:
class a
{
a();
~a();
void baseclass();
}
class b: class a
{
b();
~b();
void derivedclass1();
}
class c: class a
{
c();
~c();
void derivedclass2();
}
Calling methodology:
b derived1;
a *baseptr = &derived1; //here base pointer knows that i'm pointing to derived class b.
baseptr->derivedclass1();
In the above calling methodology, the base class knows that it's pointing to derived class b.
So where does the ambiguity exist?
In what cases will the function definitions get resolved at runtime?
This code, at run time, calls the correct version of f() depending on the type of object (A or B) that was actually created - no "ambiguity". The type cannot be known at compile-time, because it is selected randomly at run-time.
struct A {
virtual ~A() {}
virtual void f() {}
};
struct B : public A {
virtual void f() {}
};
int main() {
A * a = 0;
if ( rand() % 2 ) {
a = new A;
}
else {
a = new B;
}
a->f(); // calls correct f()
delete a;
}
There is no ambiguity exists in the example provided.
If the base class has the same function name as the derived class, and if you call in the way you specified, it will call the base class's function instead of the derived class one.
In such cases, you can use the virtual keyword, to ensure that the function gets called from the object that it is currently being pointed. It is resolved during the run time.
Here you can find more explanation..
Turn this
void baseclass();
to
virtual void baseclass();
Override this in your Derived classes b and c. Then
b *derived1 = new derived1 ();
a *baseptr = derived1; //base pointer pointing to derived class b.
baseptr->baseclass();
will invoke derived1 definition, expressing run time polymorphism. And do remember about making your destructor virtual in Base. Some basic reading material for polymorphism
Runtime means that exact method will be known only at run time. Consider this example:
class BaseClass
{
public:
virtual void method() {...};
};
class DerivedClassA : public BaseClass
{
virtual void method() {...};
};
class DerivedClassB : public BaseClass
{
virtual void method() {...};
};
void func(BaseClass* a)
{
a->method();
}
When you implement your ::func() you don't know exactly type of instance pointed by BaseClass* a. It might be DerivedClassA or DerivedClassB instance etc.
You should realize, that runtime polymorphism requires special support from language (and maybe some overhead for calling "virtual" functions). In C++ you "request" for dynamic polymorphism by declaring methods of base class "virtual" and using public inheritance.
You need to have some useful business method declared in the base and in each derived class. Then you have code such as
a->someMethod();
Now the a pointer might point to an instance of any of the derived classes, and so the type of what a is pointing to must determine which someMethod() is called.
Lets have an experiment
#include <iostream>
using namespace std;
class aBaseClass
{
public:
void testFunction(){cout<<"hello base";}///Not declared as virtual!!!!
};
class aDerivedClass:public aBaseClass
{
public:
void testFunction(){cout<<"hello derived one";}
};
class anotherDerivedClass:public aDerivedClass
{
public:
void testFunction(){cout<<"hello derived two";}
};
int main()
{
aBaseClass *aBaseClassPointer;
aBaseClassPointer=new aDerivedClass;
aBaseClassPointer->testFunction();
}
The above code does not support run time polymorphism. Lets run and analyze it.
The output is
hello base
Just change the line void testFunction(){cout<<"hello base";} to virtual void testFunction(){cout<<"hello base";} in aBaseClass. Run and analyze it. We see that runtime polymorphism is achieved. The calling of appropriate function is determined at run time.
Again change the line aBaseClassPointer=new aDerivedClass to aBaseClassPointer=new anotherDerivedClass in main function and see the output. Thus the appropriate function calling is determined at run time (when the program is running).
Update: This issue is caused by bad memory usage, see solution at the bottom.
Here's some semi-pseudo code:
class ClassA
{
public:
virtual void VirtualFunction();
void SomeFunction();
}
class ClassB : public ClassA
{
public:
void VirtualFunction();
}
void ClassA::VirtualFunction()
{
// Intentionally empty (code smell?).
}
void ClassA::SomeFunction()
{
VirtualFunction();
}
void ClassB::VirtualFunction()
{
// I'd like this to be called from ClassA::SomeFunction()
std::cout << "Hello world!" << endl;
}
The C# equivalent is as follows: Removed C# example, as it's not relevant to the actual problem.
Why isn't the ClassB::VirtualFunction function being called when called from ClassA::SomeFunction? Instead ClassA::VirtualFunction is being called...
When I force implementation of the virtual function ClassA::VirtualFunction, like so:
class ClassA
{
public:
virtual void VirtualFunction() = 0;
void SomeFunction();
}
class ClassB : public ClassA
{
public:
void VirtualFunction();
}
void ClassA::SomeFunction()
{
VirtualFunction();
}
void ClassB::VirtualFunction()
{
// I'd like this to be called from ClassA::SomeFunction()
std::cout << "Hello world!" << endl;
}
The following error occurs at runtime, despite the derrived function deffinately being declared and defined.
pure virtual method called
terminate called without an active exception
Note: It seems like the error can be caused even by bad memory usage. See self-answer for details.
Update 1 - 4:
Comments removed (not releavnt).
Solution:
Posted as an answer.
class Base {
public:
virtual void f() { std::cout << "Base" << std::endl; }
void call() { f(); }
};
class Derived : public Base {
public:
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main()
{
Derived d;
Base& b = d;
b.call(); // prints Derived
}
If in the Base class you do not want to implement the function you must declare so:
class Base {
public:
virtual void f() = 0; // pure virtual method
void call() { f(); }
};
And the compiler won't allow you to instantiate the class:
int main() {
//Base b; // error b has a pure virtual method
Derived d; // derive provides the implementation: ok
Base & b=d; // ok, the object is Derived, the reference is Base
b.call();
}
As a side note, be careful not to call virtual functions from constructors or destructors as you might get unexpected results.
If you're getting that 'pure virtual method called
terminate called without an active exception' error message, that means you're calling the virtual function from the constructor or destructor of classA (the base class), which you should not do.
on the pure virtual method called error:
You should create a different question as it is in fact different than the other. The answer to this question is on the very last paragraph of my previous answer to your initial question:
Do not call virtual functions from constructors or destructors
class Base
{
public:
Base() { f(); }
virtual void f() = 0;
};
class Derived : public Base
{
public:
virtual void f() {}
};
int main()
{
Derived d; // crashes with pure virtual method called
}
The problem in the code above is that the compiler will allow you to instantiate an object of type Derived (as it is not abstract: all virtual methods are implemented). The construction of a class starts with the construction of all the bases, in this case Base. The compiler will generate the virtual method table for type Base, where the entry for f() is 0 (not implemented in base). The compiler will execute the code in the constructor then. After the Base part has completely been constructed, construction of the Derived element part starts. The compiler will change the virtual table so that the entry for f() points to Derived::f().
If you try calling the method f() while still constructing Base, the entry in the virtual method table is still null and the application crashes.
When A calls VirtualFunction() it will automatically call the version on B. That is the point of virtual functions.
I am not as familiar with the C++ syntax tho. Do you have to declare the function to be virtual at the point of the body as well as in the header?
Alsop, in class B you probably need to mark it as override
in C# its easy. I just don't know the c++ syntax.
public class ClassA
{
public **virtual** void VirtualFunction(){}
public void FooBar()
{
// Will call ClassB.VirtualFunction()
VirtualFunction();
}
}
public class ClassB
{
public **overide** void VirtualFunction()
{
// hello world
}
}
If you want to force the derived classes to implement the VirtualFunction:
class ClassA
{
public:
virtual void VirtualFunction()=0;
void SomeFunction();
}
This is C++. Default the derived function will be called.
If you want to call the base-class function do:
void ClassA::SomeFunction()
{
// ... various lines of code ...
ClassA::VirtualFunction();
}
There's nothing wrong with your code but your sample is incomplete. You do not state where you are calling SomeFunction from.
As has already been pointed out by dribeas you must be careful calling virtual functions from your constructor as the virtual tables are only built up as each class in the hierarchy completes construction.
Edit: The following paragraph of my reply was incorrect. Apologies. It is fine to call SomeFunction from the constructor of ClassB as the vtable is in place (at least) by the end of the initialiser list i.e. once you are in the body of the constructor. It is not fine to call it from ClassA's constructor of course.
Original paragraph:
I suspect you must be calling SomeFunction from the constructor of ClassB at which point only the vtable up to type ClassA will be complete i.e. to the virtual dispatch mechanism your class is still of type ClassA. It only becomes an object of type ClassB when the constructor completes.
To call a virutal function function you need to call via a pointer or a reference.
void ClassA::SomeFunction()
{
VirtualFunction(); // Call ClassA::VirtualFunction
this->VirtualFunction(); // Call Via the virtual dispatch mechanism
// So in this case call ClassB::VirtualFunction
}
You need to be able to distinguish the two different types of call otherwise the classA::VirtualFunction() becomes inaccessible when it is overridden.
As pointed out by others if you want to make the base class version abstract then use the = 0 rather than {}
class A
{
virtual void VirtualFunction() =0;
....
But sometimes it is legitimate to have an empty definition. This will depend on your exact usage.
You aren't defining the function in ClassB correctly, it should be:
public class ClassB
{
public void override AbstractFunction()
{
// hello world
}
}
Then, any call from the base class to virtual/abstract methods will call the implementation on the derived instance.