virtual function call from base class

2019-01-21 09:02发布

Say we have:


Class Base
{   
    virtual void f(){g();};
    virtual void g(){//Do some Base related code;}
};

Class Derived : public Base
{   
    virtual void f(){Base::f();};
    virtual void g(){//Do some Derived related code};
};

int main()
{
    Base *pBase = new Derived;
    pBase->f();
    return 0;  
}

Which g() will be called from Base::f()? Base::g() or Derived::g()?

Thanks...

8条回答
【Aperson】
2楼-- · 2019-01-21 09:28

pBase is a pointer to a base. pBase = new Derived returns a pointer to a Derived - Derived is-a Base.

So pBase = new Derived is valid.

pBase references a Base, so it will look at Derived as if it were a Base.

pBase->f() will call Derive::f();

Then we see in the code that:

Derive::f() --> Base::f() --> g() - but which g??

Well, it calls Derive::g() because that is the g that pBase "points" to.

Answer: Derive::g()

查看更多
不美不萌又怎样
3楼-- · 2019-01-21 09:28

As you have defined g() to be virtual, the most derived g() will be looked up in the vtable of the class and called regardless of the type your code is currently accessing it.

See the C++ FAQ on virtual functions.

查看更多
Juvenile、少年°
4楼-- · 2019-01-21 09:30

The derived class' method will be called.

This is because of the inclusion of vtables within classes that have virtual functions and classes that override those functions. (This is also known as dynamic dispatch.) Here's what's really going on: a vtable is created for Base and a vtable is created for Derived, because there is only one vtable per class. Because pBase is calling upon a function that is virtual and overrode, a pointer to the vtable for Derived is called. Call it d_ptr, also known as a vpointer:

int main()
{
    Base *pBase = new Derived;
    pBase->d_ptr->f();
    return 0;  
}

Now the d_ptr calls Derived::f(), which calls Base::f(), which then looks at the vtable to see what g() to use. Because the vpointer only knows g() in Derived, that's the one we use. Therefore, Derived::g() is called.

查看更多
【Aperson】
5楼-- · 2019-01-21 09:33

Well... I'm not sure this should compile. The following,

Base *pBase = new Derived;

is invalid unless you have:

Class Derived : public Base

Is it want you meant? If this is want you meant,

pBase->f();

Then the call stack would go like this:

Derived::f()
    Base::f()
        Derived::g()
查看更多
劫难
6楼-- · 2019-01-21 09:38

Actually running your code shows that Derived::g() is called.

查看更多
成全新的幸福
7楼-- · 2019-01-21 09:38

I think you trying to invent Template Method Pattern

查看更多
登录 后发表回答