2016-06-29 31 views
0

我似乎无法理解编译器的优先级如何去哪个函数。 这里是一个例子代码:C++继承选择函数的优先级

#include <iostream> 
using namespace std; 

class A{ 
public: 
    int f() {return 1;} 
    virtual int g() {return 2;} 
}; 
class B: public A { 
public: 
    int f() {return 3;} 
    virtual int g() {return 4;} 
}; 
class C: public A{ 
public: 
    virtual int g() {return 5;} 
}; 
int main() { 
    A *pa; 
    B b; 
    C c; 

    pa = &b; 
    cout<< pa -> f()<<endl<<pa -> g() << endl; 
    pa = &c; 
    cout<< pa -> f() << endl; cout<< pa -> g() << endl; 

    return 0; 
} 

哪个函数(G()和f())将每个时间称为为什么?

+2

运行该程序找出并返回这里,如果你不能找出*为什么*代码的行为就像它一样。但首先,尝试使用关于虚拟调度的知识来解释自己。 – user2079303

+0

我跑了它,问题是为什么... – user107761

+1

如果你跑了它,那么你一定知道哪个函数被调用,你不是吗?你确实问过。 – user2079303

回答

0

在第一个序列中,它将调用A::f()B::g()

在第二个序列中,它将调用A::f()C::g()

原因是f()作为非虚拟方法在编译期间根据变量类型(指向A)解析。 g()A中被标记为虚拟方法,因此运行时解析完成并且将始终调用实际实例的方法(BC)。

1

pa->f()总是会调用A::f(),不管你做pa点,因为paA*A::f虚拟

  • 如果pa指向B(第一顺序),它会调用B::g()

    pa->g()A::g()B::g()C::g()取决于什么pa点使用polymorphism因为A::g虚拟调用。

  • 如果pa指向C(第二个序列),它将调用C::g()
0

当你说一个函数是virtual时,你告诉编译器使用后期绑定而不是静态绑定。 因此在编译期间A::f()将是静态绑定,所以它是固定调用哪种方法体。 另一方面,A::g()在编译期间不会绑定到任何方法体。它将在运行时决定调用哪个方法体(使用vptr)。

A *pa; //no matter what object you assign to pa, A::fa() will always be called 
pa = &b; 
pa->f();//calls A::f() 

pa->g();// remember what function body to be called will be decided at runtime. 
//will call B::f() 

pa = &c; 
pa->g(); //will call C::g()