Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
289 views
in Technique[技术] by (71.8m points)

c++ - Virtual function calling a non-virtual function

I wrote the following piece of code to test my understanding of virtual inheritance. Apparently, I still don't get it fully. Here is my code (followed by my question):

#include <iostream>
#include <vector>

using namespace std;

class Foo
{
public:
    virtual void foo();
    void foo2();
};

void Foo::foo()
{
    cout << "In FOO - foo 1" << endl;
    foo2();
}

void Foo::foo2()
{
    cout << "In FOO - foo 2" << endl;
}

class Bar : public Foo
{
public:
    void foo();
    void foo2();
};

void Bar::foo()
{
    cout << "In BAR - foo 1" << endl;
    foo2();
}

void Bar::foo2()
{
    cout << "In BAR - foo 2" << endl;
}

int main()
{
    Foo* f = new Foo;
    f->foo();

    Foo* b = new Bar;
    b->foo();

    return 0;
}

This is my understanding:

The pointer f points to the base class Foo and f->foo() calls foo() in the base class which in turn calls foo2() in the base class.

The pointer b is a base-class pointer but points to an object of the derived class Bar. Now, since foo() is a virtual function, it calls foo() of the derived class. Now foo() (of the derived class) calls foo2(). Since foo2() is not a virtual function, I was expecting the base class foo2() to get called. However I see that foo2() of the derived class is getting called.

So, I was expecting this output:

In FOO - foo 1
In FOO - foo 2
In BAR - foo 1
In FOO - foo 2

but got this instead:

In FOO - foo 1
In FOO - foo 2
In BAR - foo 1
In BAR - foo 2

Why is this so? From what I understand, the vtable will have an entry only for foo() and not for foo2(). So, how is foo2() of the derived class getting called?

This is my first post. Please excuse me if I have broken any posting guidelines. Thanks in advance!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In Bar::foo(), you are calling foo2(). This is really equivalent to calling this->foo2(). The type of this is Bar, so this is really equivalent to:

void Bar::foo()
{
    Bar *bar = this;
    bar->foo2();
}

So there's no polymorphism involved at this point; the call is resolved to Bar::foo2 at compile-time, rather than dynamically at run-time.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...