C++为了使用多态的特性,引入了虚函数。
虚函数的作用是允许在子类中重新定义与父类同名的函数,并且可以通过父类的指针或引用来访问父类和子类中的同名函数。
所以只有重写了虚函数才能算作体现了C++的多态特性。
虚函数的使用:
1、在父类中用virtual来修饰要实现多态的函数,这样的函数就被称为虚函数。
这样就可以在子类中重新定义此函数,为它赋予新功能,并能方便地进行调用。
2、在子类中重新定义此函数,要求函数名,函数类型、返回值类型,函数参数个数和类型全部与父类的虚函数相同,并要根据子类的需要重新定义函数功能。
C++规定,当一个成员函数被定义为虚函数后,其子类中的同名函数都自动成为虚函数。
因此在子类重写虚函数的时候,可以不写virtual(最好写一下,看得清楚)。
如果子类并没有重写虚函数,则子类简单地继承其直接父类的虚函数。
3、定义父类指针,并使该指针指向同一类族中的需要调用“那个虚函数”的对象的内存地址。
4、通过该指针调用虚函数,此时调用的就是相应的虚函数。
注意:
1、只有类的成员函数才能定义为虚函数。
2、静态成员函数不能是虚函数,因为它不受限于某个对象。
3、内联函数不能是虚函数。
4、构造函数不能是虚函数。
5、析构函数可以是虚函数。
代码示例:
class Shape //父类
{
public:
double calcArea()
{
cout<<"calcArea"<<endl;
return 0;
}
};
class Circle:public Shape //子类1
{
public:
Circle(double r); //构造函数功能实现部分省略
double calcArea()
{
return 3.14*m_dR*m_dR;
}
private:
double m_dR;
};
class Rect:public Shape //子类2
{
public:
Rect(double width,double height); //构造函数功能实现部分省略
double calcArea()
{
return m_dWidth*m_dHeight;
}
private:
double m_dWidth;
double m_dHeight;
};
int main() //主函数
{
Shape *shape1=new Circle(4.0);
Shape *shape2=new Rect(3.0,5.0);
shape1->calcArea();
shape2->calcArea();
......
return 0;
}
如上所示,不使用virtual,虚函数。调用的结果只会是父类的calcArea函数被调用。所以这时应该使用虚函数。
class Shape //父类
{
public:
virtual double calcArea() //把要实现多态的函数写为虚函数
{
cout<<"calcArea"<<endl;
return 0;
}
};
class Circle:public Shape //子类1
{
public:
Circle(double r); //构造函数功能实现部分省略
virtual double calcArea() //函数名相同的函数写为虚函数(此时不是必须,
{ 如果省略,编译器将会自动添加)
return 3.14*m_dR*m_dR;
}
private:
double m_dR;
};
class Rect:public Shape //子类2
{
public:
Rect(double width,double height); //构造函数功能实现部分省略
virtual double calcArea() //同上
{
return m_dWidth*m_dHeight;
}
private:
double m_dWidth;
double m_dHeight;
};
int main() //主函数
{
Shape *shape1=new Circle(4.0);
Shape *shape2=new Rect(3.0,5.0);
shape1->calcArea();
shape2->calcArea();
......
delete shape1;
...
delete shape2;
...
return 0;
}
如上例,此时调用的结果就是相应的函数被调用。