0

**Read the below mention code **

#include<iostream>
using namespace std;

class FR
{
public :
    virtual int fun() 
    {
      cout<<"In FR Class "<<endl;
    }

    int Threading()
    {
        fun();
    }
};

class FD : public FR
{
public :
    int fun()
    {
        cout<<" In FD class "<<endl;
    }
};

int main()
{
    FD obj ;

    obj.Threading();
}

Here,output of this is "in FD class".

here we have inheritance the FR class into FD class,so all property from the FR class is inheritade from the based class, but when we call the Threading() function using the FD object than it will called the based class but for Threading class Fun() function is available as virtual and Fun definition is also available so why it not classed the based class Fun() function.

I'm expecting that when we called the Threading() function than it should be called the class FR Fun() function not class FD Fun().

Actual OutPut : "In FD Class"

Expected OutPut : "In FR Class"

6
  • 1
    obj is an FD hence calling the method fun calls FD::fun thats what virtual is all about Commented Feb 7, 2023 at 18:34
  • what your code does is known as the Template Method Pattern. Commented Feb 7, 2023 at 18:36
  • 6
    Your expectation is based on not fully understanding what virtual does. Read that chapter again. Commented Feb 7, 2023 at 18:36
  • @463035818_is_not_a_number the GOF definition of template is at odds with the C++ definition. Commented Feb 7, 2023 at 18:39
  • @MarkRansom yes the name is unfortunate, thats why I always link an article when mentioning it. Commented Feb 7, 2023 at 18:40

3 Answers 3

3

This is known as virtual dispatch and is basically just what virtual means not more. The method to be called is determined by the dynamic type of the object.

You can think of the call as having a this->:

class FR
{
public :
    virtual int fun() 
    {
      cout<<"In FR Class "<<endl;
    }

    int Threading()
    {
        this->fun();
    }
};

When Threading is called on an object of type FD then in above code this is a FR* but the dynamic type of the object to which this points is FD. Hence when the virtual fun() is called it calls FD::fun().

If you do not want virtual dispatch for fun remove the virtual. Then your code will print "In FR Class".

Sign up to request clarification or add additional context in comments.

Comments

3

Virtual functions are called through the table of virtual function pointers.

The derived class FD overwrites the address of the virtual function fun with the address of its own overriding function in its tangle of virtual function pointers.

So in this sequence of calls

obj.Threading();

and

int Threading()
{
    fun();
}

to call the function fun the pointer to the function fun is searched in the table of virtual function pointers of the class FD and correspondingly the function definition provided in the class FD is used. then the o

4 Comments

the vtable is an implementation detail. OPs code would produce same output also when there was no vtable
@463035818_is_not_a_number But under the hood nevertheless there is used the described logic.
yes, its an implementation detail ;).
The C++ standard does not specify that you must use a vtable. It might be good to know about since it's so widely used, but it's a mistake to assume that's the only way virtual methods could be done.
1

When you declare a method as virtual, a vtable will be generated for that class (if it is concrete, i.e. has no pure virtual members) that contains pointers to each of the virtual functions in the class. A vtable will also be generated for every class that derives from the class with the virtual method (as long as they are also concrete).

Each object of the class then gets a vtable pointer that points to their particular vtable. Your class FR has a pointer to the vtable containing FR::fun, whereas your class FD has a pointer to the vtable containing FD::fun.

Since Threading is non-virtual, when Threading is called on an object of class FD, the method implemented in FR is called with a this pointer to the FD object. Then, when Threading calls this->fun it looks for the function in the FD's vtable and calls FD::fun.

5 Comments

the vtable is an implementation detail. OPs code would produce same output also when there was no vtable.
@463035818_is_not_a_number I'm not sure that this is correct, the this pointer passed to FR::Threading is of type FR*. To call fun on a pointer to an FR and get to a function implemented in FD surely you have to go through the vtable?
what I mean is that the c++ standard does not mention the vtable, it merely specifies what happens when you call a virtual method. Consider eg that there is devirtualization (quuxplusone.github.io/blog/2021/02/15/devirtualization), where no lookup must be made, because its all known at compile time already, also in such cases virtual methods work as they should.
I'm not sure that any of those examples exactly match this case. However, if the OP was only interested in exactly what the standard says they would have tagged the post as language lawyer. Since the vtable is the way in which every compiler implements virtual dispatch in practically every useful case, and the OP does not have a full understanding of what the virtual keyword means, it is useful information for them to know about the vtable and how it would actually work in this case.
yes it is useful information. Though one should not put the cart before the horse, hence I think it is also useful to add that the virtual table is just an implementation detail

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.