【问题标题】:c++ inheritance priorities of choosing functionsc++ 选择函数的继承优先级
【发布时间】:2016-06-29 13:35:13
【问题描述】:

我似乎无法理解编译器如何优先选择哪个函数。 这是一个示例代码:

#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())以及为什么?

【问题讨论】:

  • 如果您无法弄清楚为什么代码的行为方式,请运行程序以找出并在此处报告。但首先,试着用你对虚拟调度的知识来解释你自己。
  • 我跑了,问题是为什么...
  • 如果你运行它,那么你肯定知道调用了哪个函数,不是吗?你确实问过了。
  • 你实际上是在问两个问题哪个?为什么?如果您已经知道第一个的答案,那么最好不要问。我最近犯了一个类似的错误,它确实增加了很多不必要的混乱。即使它们看起来密切相关,每个问题都有一个问题总是更好

标签: c++ inheritance virtual


【解决方案1】:

pa-&gt;f() 将始终调用A::f(),无论您使pa 指向什么,因为paA*A::f 不是虚拟

pa-&gt;g() 将调用A::g()B::g()C::g(),具体取决于pa 指向使用polymorphism,因为A::g虚拟

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      当你说一个函数是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()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-10
        • 1970-01-01
        • 2010-10-11
        • 2019-06-11
        • 2012-11-26
        • 2010-11-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多