下面的代码有错误:最后一行应该是
bp->g();
问题是,如果我注释掉该行,bp->f()
实际上调用了 Derived 版本,所以我假设编译器将 bp 视为类 Derived,那么为什么在调用 g 时,编译器将bp
作为基指针。
谢谢!
#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);
}
最佳答案
您不能通过更改其参数来覆盖虚拟成员函数。也就是说,Derived::g(int)
不覆盖Base::g()
。
假设您是编译器。您看到函数调用 bp->g(1)
并且您知道 bp
是一个 Base*
。因此,您在 Base
中查找名为 g
的函数,该函数的参数是 int
。你发现了什么?没有!没有一个。
只有当在基类中发现一个函数是虚函数时,它才会考虑对象的动态类型。因此,让我们考虑调用 bp->f()
。它知道 bp
是一个 Base*
,因此它查找 Base
的一个名为 f
的成员函数,它接受没有争论。它当然会找到 Base::f()
,并且发现它是虚拟的。因为它是虚拟的,所以它会在对象的动态类型中查找相同的函数,即 Derived
。它找到 Derived::f()
并改为调用它。
关于c++ - 压倒一切?向上转型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15864410/