C++中的虚函数和子类基类指针的相互转换
虚函数
虚函数是用来动态实现多态机制的一种方式,用基类指针指向子类对象,调用子类中的成员函数,实现多态。在基类中声明成员函数时,在前面加上virtual关键字,例如:
virtual void print()
定义基类
class A
{
public:
virtual void print()
{
cout << 'A' << endl;
}
void fun1()
{
cout << "base" << endl;
}
};
在基类中定义两个成员函数,其中print()是虚函数,fun1()是普通函数
定义子类
class B :public A
{
public:
virtual void print()
{
cout << 'B' << endl;
}
void fun1()
{
cout << "child" << endl;
}
};
A* pA = new A(); //声明基类对象
pA->print(); //调用基类的成员函数print(),输出A
pA->fun1(); //调用基类的成员函数fun1(),输出base
B* pB = (B*)pA; //子类指针指向基类对象,pB是指向基类对象的指针
pB->print(); //由于print()是虚函数,所以pB调用基类的成员函数printf(),输出A
pB->fun1(); //由于fun1()不是虚函数,所以pB调用子类的成员函数fun1(),输出child
总结:
当子类指针指向基类对象时,这个指针调用的是谁的成员函数呢?答:当成员函数是虚函数时,调用的是基类的成员函数,否则,调用子类的成员函数。
pA = new B(); //基类指针指向子类对象
pA->print(); //由于print()是虚函数,所以pA调用子类的成员函数,输出B,实现了多态
pA->fun1(); //由于fun1()不是虚函数,所以pA调用基类的成员函数,输出base
pB = (B*)pA; ///子类指向基类对象,因为pA本来就指向子类对象,所以pB也是指向子类对象的,此时,不管成员函数是不是虚函数,pB都会调用子类的成员函数
pB->print(); //输出B
pB->fun1(); //输出child
main函数
int main()
{
A* pA = new A();
pA->print();//调用基类的方法,输出A
pA->fun1();//输出base
B* pB = (B*)pA;
pB->print();//调用基类的方法,输出A,pB是指向基类对象的指针,print是虚函数,所以调用基类的成员函数
pB->fun1();//输出child,fun1()不是虚函数,所以调用子类的成员函数
pA = pB;
pA->print();//输出A
pA->fun1();//输出base
delete pA, pB;
pA = new B();//基类指针指向子类对象,调用子类中的虚函数
pA->print();//输出B
pA->fun1();//输出base
pB = (B*)pA;
pB->print();//输出B
pB->fun1();//输出child
return 0;
}
输出结果为: