下面的代码有错误:最后一行应该是
bp->g();
问题是,如果我注释掉这一行,bp->f()
实际上调用了派生版本,所以我假设编译器将bp作为类派生,那么为什么当调用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);
}
发布于 2013-04-07 16:00:43
您不能通过更改虚拟成员函数的参数来覆盖它。也就是说,Derived::g(int)
没有覆盖Base::g()
。
假设你是编译器。您可以看到函数调用bp->g(1)
,并且知道bp
是一个Base*
。因此,您可以查找Base
,以查找一个名为g
的函数,该函数接受一个参数,即int
。你发现什么了?没什么!根本就没有。
只有在基类中找到一个函数为虚拟函数时,它才会考虑对象的动态类型。因此,让我们考虑调用bp->f()
。它知道bp
是一个Base*
,所以它查找Base
的一个不带参数的成员函数f
。当然,它找到了Base::f()
,并且看到它是虚拟的。因为它是虚拟的,所以它在对象的动态类型(即Derived
)中查找相同的函数。它找到了Derived::f()
,并调用了它。
发布于 2013-04-07 16:00:44
之所以会发生这种情况,是因为Derived::g
不覆盖Base::g
。它是一种完全独立的方法,恰好具有相同的名称。这两种方法是不相关的,因为它们采用不同的论点。
因此,当您调用bp->g(1)
时,Base
也碰巧有一个名为g
的方法这一事实完全无关紧要。
发布于 2013-04-07 16:05:43
派生类现在不覆盖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 << "Derived::g()" << endl; }
是派生类的自主方法,它不覆盖Base::g
,因为没有一个Base::g
使用int
参数。
https://stackoverflow.com/questions/15864410
复制相似问题