【问题标题】:C++ overloaded method binding with virtual inheritance使用虚拟继承的 C++ 重载方法绑定
【发布时间】:2013-10-17 20:48:42
【问题描述】:

好的,我有一个关于以下代码输出的问题(即 111222223)

#include <iostream>
struct C {
 virtual int eq(const C& other) const { return 1; }
};
struct SC : C {
 virtual int eq(const C& other) const { return 2; } 
 virtual int eq(const SC& other) const { return 3; }
};
void go(const C& c, const C& c1, const SC& sc) {
 using namespace std;

 cout << c.eq(c) << endl;
 cout << c.eq(c1) << endl;
 cout << c.eq(sc) << endl;

 cout << c1.eq(c) << endl;
 cout << c1.eq(c1) << endl;
 cout << c1.eq(sc) << endl;

 cout << sc.eq(c) << endl;
 cout << sc.eq(c1) << endl;
 cout << sc.eq(sc) << endl;
}
int main(int argc, const char* argv[]) { 
 go(C(), SC(), SC());
 return 0;
}

所以我知道我正在使用带有引用的点运算符,该引用将根据调用者的运行时类型动态绑定正确的虚拟方法(需要 -> 带有指针,但在这里动态思维可以)。我不明白为什么倒数第二行打印'2'而不是'3'。这是因为方法签名是静态的,所以方法是根据正确派生类型 SC 中的静态签名选择的?提前感谢您的帮助!

【问题讨论】:

    标签: c++ overloading virtual-inheritance method-signature


    【解决方案1】:

    在 C++ 中不支持多次分派,仅支持调用函数的对象(动态分派仅适用于this 指针)。在表达式中:

    sc.eq(c1);
    

    编译器会分派到动态类型sc,但会使用静态类型c1

    【讨论】:

      【解决方案2】:

      这是由于函数解析规则造成的。

      在本次通话中:

      sc.eq(c1);
      

      只有一个函数可以被调用,一旦 c1 的类型为 struct Ceq 动态重载。

      但在通话中

      sc.eq(sc);
      

      您有两个可能的eq 函数要调用。第一个在struct C 中声明,动态重载eq,第二个在struct SC 中声明。一旦scstruct SC 类型,最后一种方法比前者更可行。

      这就是你得到3 的原因。

      【讨论】:

      • @ThomasBadan 你如何解释 c1.eq(sc);返回 2? c1 是struct SC 的一个实例,而参数sc 的类型是struct SC,所以它应该返回3,不是吗?
      • @IgorPopov 只有 sc 的类型为 struct SC。 c1的类型是struct C(看go函数的定义,即使原来的对象是SC),所以它只知道动态重载eq。即virtual int eq(const C&amp; other) const { return 2; }.
      • @ThomasBadan +1,现在我对子类化和绑定有了更好的理解 :)
      • @ThomasBadan 我的最后一个问题:c 类型的struct C 类型的c.eq(sc) 对象如何知道scstruct C 类型中的这种类型的参数没有声明 eq
      • @IgorPopov sc 也是struct C 类型。看它的声明。它是struct C(继承)的后代。因此,任何期望 struct C 的函数都可以用于传递声明为它的后代的对象(在本例中为 sc)。因此,在sc.eq(sc) 的情况下,有两个可以调用的函数。第一个具有参数struct C,sc 是其中的一种。第二个有参数struct SC,sc也是一种。重载决议规则说第二个比前者更可行。
      猜你喜欢
      • 2015-09-09
      • 2017-03-31
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      相关资源
      最近更新 更多