#include <iostream>
using namespace std;
class BaseClass {
public:
virtual void fn1() {
cout << "BaseClass:fn1()" << endl;
}
void fn2() {
cout << "BaseClass:fn2()" << endl;
}
};
class DerivedClass : public BaseClass {
public:
void fn1() override {
cout << "DerivedClass:fn1()" << endl;
}
void fn2() {
cout << "DerivedClass:fn2()" << endl;
}
};
int main() {
DerivedClass dc;
BaseClass *pb = &dc;
DerivedClass *pd = &dc;
pb->fn1();
pb->fn2();
pd->fn1();
pd->fn2();
return 0;
}
程序运行结果如下:
DerivedClass:fn1()
BaseClass:fn2()
DerivedClass:fn1()
DerivedClass:fn2()
-
pb->fn1();
: 使用指向基类的指针调用虚函数fn1()
。由于fn1()
在基类中被声明为虚函数,因此在运行时会根据对象的实际类型进行动态绑定。因为指针pb
指向的是一个DerivedClass对象,所以调用的是DerivedClass中的fn1()
,输出DerivedClass:fn1()
。 -
pb->fn2();
: 使用指向基类的指针调用非虚函数fn2()
。非虚函数在编译时就会确定调用的版本,因此无论指针类型是什么,都会调用基类的版本,输出BaseClass:fn2()
。 -
pd->fn1();
: 使用指向派生类的指针调用虚函数fn1()
。同样,由于fn1()
是虚函数,会根据对象的实际类型进行动态绑定。指针pd
指向的是一个DerivedClass对象,所以调用的是DerivedClass中的fn1()
,输出DerivedClass:fn1()
。 -
pd->fn2();
: 使用指向派生类的指针调用非虚函数fn2()
。与第二步相似,非虚函数在编译时就会确定调用的版本,因此无论指针类型是什么,都会调用派生类的版本,输出DerivedClass:fn2()
。 -
由于虚函数的动态绑定特性,调用基类和派生类的虚函数会根据对象的实际类型来确定调用哪个版本,而对于非虚函数,则根据指针的类型来确定调用哪个版本。