【问题标题】:runtime binding and virtual inheritence运行时绑定和虚拟继承
【发布时间】:2015-02-12 16:38:22
【问题描述】:
class Base {
  public:
  virtual int f() const {
       cout << "Base::f()\n";
       return 1;
}
 virtual void f(string) const {}
 virtual void g() const {}
};

class Derived4 : public Base {
  public:
       int f(int) const {
         cout << "Derived4::f()\n";
         return 4;
    }
};

int main()
{
    string s("hello");

    Derived4 d4;
    Base& br = d4; // Upcast
    // br.f(1); // Derived version unavailable
    br.f(); // why does it compile and run?
    br.f(s);// why does it compile and run?
}

在派生中:重载基址的f() .. 所以所有基址f() 版本都应该被隐藏。
现在,对于 br.f()br.f(s) :由于运行时绑定,应该调用派生的 f()f(s),但是它们应该隐藏,代码仍然编译并执行 int Base::f() 和 void Base::f(string)。

Q1:我缺少什么?
Q2:br.f(1) 无法编译,因为在编译期间会执行类型检查,而 int f(int) 是Base 中不存在。我说的对吗?

【问题讨论】:

  • 你没有在派生类中重载任何东西!!!函数f 的原型不同于基类中函数f 的任何原型。此外,目前还不清楚您所说的“隐藏”是什么意思。函数f()f(string) 是基类中的public,因此使用基对象调用它们应该没有问题。
  • Base ::int f() , Derived ::int f(int) ,你的意思是这不是超载?
  • 它们是隐藏的,所以如果你尝试d4.f()d4.f(s),它不会编译。但是br的类型是Base,编译器不知道它的真实类型(Derived4),所以br.f()br.f(s)都可以。
  • 好吧,我不会称它为“隐藏”,只是您的Derived 版本的f 使编译器无法理解您正在尝试调用f基类。另外,你现在说br.f()br.f(s) 都可以,所以我不太明白你的问题是什么。
  • 这不是“虚拟继承”...

标签: c++ inheritance


【解决方案1】:

基类永远不知道派生类中新添加的成员,它只知道自己声明的成员的信息。
因此,当派生类实例d4 分配给基类引用br 时,新添加的方法int f(int) const 将隐藏到br。这就是下面代码编译错误的原因

// br.f(1); // Derived version unavailable

下面两行编译成功

br.f();
br.f(s);

更多了解:

class Base {
  public:
  virtual int f() const {
       cout << "Base::f()\n";
       return 1;
}
 virtual void f(string) const {}
 virtual void g() const {}
};

class Derived4 : public Base {
  public:
       int f(int) const {
         cout << "Derived4::f()\n";
         return 4;
    }
    void g() const {
         cout<< "Derived4::g()" << endl;
    }
};

int main()
{
    string s("hello");

    Derived4 d4;
    Base& br = d4; // Upcast
    // br.f(1); // Derived version unavailable
    br.f(); // No Compilation error
    br.f(s);// No Compilation error

    d4.f();  // Compilation error
    d4.f(s); // Compilation error
    d4.f(1); // No Compilation error
    d4.g();  // No Compilation error
    br.g();  // Will print - "Derived4::g()"
}

希望对你有帮助!

【讨论】:

    【解决方案2】:

    函数int Derived4::f(int) 隐藏基类中的函数,但不会覆盖它们。为此,它应该具有完全相同的签名。

    在函数覆盖的情况下,您可以在基类引用上调用该函数并查看被调用的派生类函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-26
      • 2013-08-24
      • 1970-01-01
      相关资源
      最近更新 更多