当子类重写父类的普通函数时,如果父类指针指向的是子类对象,那么调用该函数时会根据指针的静态类型调用相应的函数。这种情况下,父类指针无法访问子类中重写的函数,而是调用父类的函数。如果需要访问子类中的函数,需要将父类指针转换为子类指针。
下面是一个示例代码,演示了继承中重写函数的情况:
#include <iostream>
using namespace std;
class Base {
public:
void print() { cout << "Base::print()" << endl; }
};
class Derived : public Base {
public:
void print() { cout << "Derived::print()" << endl; }
};
int main() {
Base* b = new Base();
Derived* d = new Derived();
// 调用父类的print()函数
b->print(); // 输出 Base::print()
// 调用子类的print()函数
d->print(); // 输出 Derived::print()
// 父类指针指向子类对象,调用父类的print()函数
b = d;
b->print(); // 输出 Base::print()
// 将父类指针转换为子类指针,调用子类的print()函数
d = dynamic_cast<Derived*>(b);
d->print(); // 输出 Derived::print()
return 0;
}
在上面的代码中,首先创建了一个父类对象 b
和一个子类对象 d
,分别调用它们的 print()
函数,可以看到父类对象调用的是父类函数,而子类对象调用的是子类函数。
接着将父类指针 b
指向子类对象 d
,再次调用 print()
函数,此时会调用父类的函数。
最后,将父类指针转换为子类指针 d
,再次调用 print()
函数,此时调用的是子类的函数。
因此,在继承中重写普通函数时,需要注意指针的静态类型和动态类型,以及可能需要进行类型转换。
重点
如果不使用虚函数,父类的指针只能访问到父类中定义的方法,而不能访问子类中同名的方法。如果子类中定义了一个和父类同名的方法,那么当通过父类的指针调用该方法时,实际上调用的是父类中的方法,而不是子类中的方法。这种情况下,如果我们希望通过父类的指针来调用子类中的同名方法,就需要将该方法声明为虚函数。
如果使用虚函数,则可以通过在父类中定义虚函数,让子类重写这些函数并实现自己的行为,从而实现通过父类指针调用子类方法的功能。