【问题标题】:overriding? upcasting?压倒一切?上扬?
【发布时间】:2013-04-07 15:57:38
【问题描述】:

以下代码有问题:最后一行应该是
bp->g();
问题是,如果我注释掉那行,bp->f() 实际上调用了 Derived 版本,所以我假设编译器将 bp 视为类 Derived,那么为什么在调用 g 时,编译器将 bp 视为 Base 指针。

谢谢!

#include <iostream>
using namespace std;

class Base {
public:
    virtual void f() const { cout << "Base::f()\n"<< endl; }
    virtual void g() const { cout << "Base::g()\n"<< endl; }
};

class Derived : public Base {
public:
    void f() const {cout << "Derived::f()" << endl; }
    void g(int) const {cout << "Derived::g()" << endl; }
};

int main() {
    Base* bp = new Derived;
    bp->f();
    bp->g(1);
}

【问题讨论】:

  • 在驱动类 void g(int ??) 缺少变量名。
  • @GrijeshChauhan 该变量未使用,因此不需要名称。
  • @juanchopanza 好的,我刚刚注意到
  • 您只能从指向Base 的指针调用Base 的公共接口中的方法,但调用会被分派到派生类型。

标签: c++ virtual overriding


【解决方案1】:

您不能通过更改其参数来覆盖虚拟成员函数。也就是说,Derived::g(int)不会覆盖Base::g()

假设你是编译器。您会看到函数调用bp-&gt;g(1),并且您知道bpBase*。因此,您在Base 中查找一个名为g 的函数,该函数接受一个int 的参数。你发现了什么?没有!一个都没有。

只有在基类中发现一个函数是虚函数时,它才会考虑对象的动态类型。所以让我们考虑一下电话bp-&gt;f()。它知道bpBase*,所以它查找Base 的一个成员函数f,它不带参数。它当然会找到Base::f(),并认为它是虚拟的。因为它是虚拟的,所以它会在对象的动态类型中查找相同的函数,即Derived。它会找到 Derived::f() 并调用它。

【讨论】:

    【解决方案2】:

    这是因为Derived::g 没有覆盖Base::g。这是一个完全独立的方法,恰好具有相同的名称。这两种方法不相关,因为它们采用不同的参数。

    因此,当您调用 bp-&gt;g(1) 时,Base 也恰好有一个名为 g 的方法这一事实完全无关紧要。

    【讨论】:

      【解决方案3】:

      您的 Derived 类现在不会覆盖 Base::g()

      class Derived : public Base {
      public:
      //...
          void f() const {cout << "Derived::f()" << endl; }
          void g() const {cout << "Derived::g()" << endl; } // <- add this, it is overriding Base::g() const
      //...
      };
      

      方法:void g(int) const {cout &lt;&lt; "Derived::g()" &lt;&lt; endl; } 是 Derived 类的自主方法,它不会覆盖 Base::g,因为 Base::g 都不接受 int 参数。

      【讨论】:

        【解决方案4】:

        实际上,您的示例应该在行中给出编译时错误 bp->g(1); 在这两种情况下,编译器都将 bp 视为具有 2 个虚函数 void f() 和 void g() 的 Base*,其中 f() 在 Derived 中被覆盖,因此当您调用 bp->f() 时,将通过 vtable 调用 Derived 版本。但是 Base 中没有 void g(int),因此 bp->g(1) 会导致编译时错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-24
          • 1970-01-01
          • 2012-10-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多