纯虚函数:纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”.纯虚函数不能实例化对象。
虚函数:虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数,是C++中多态性的一个重要体现。利用基类指针访问派生类中的虚函数,这种情况下采用的是动态绑定技术。
动态绑定:基类指针是调用派生类的中的成员函数还是调用基类中的成员函数要到程序运行时确定。主要看此时基类指针所指向的对象。
这里要涉及一些很重要的概念,也是我最近看完Effective C++才明白的东西,记录下来。这些概念就是静态类型和动态类型,静态绑定和动态绑定。静态绑定和动态绑定。静态绑定是说前期绑定。
所谓对象的静态类型,就是它在程序中被声明的时候采用的类型。
考虑下面的class继承体系:
class Shape{
virtual void draw(color = Red) const=0;
...
...
};
class Rectangle:public Shape{
virtual void draw(color = Red) const;
...
...
};
class Circle:public Shape
{
virtual void draw(color = Red) const;
...
...
};
现在考虑以下这些指针:
Shape* ps;//静态类型为Shape*
Shape*pc =new Circle;//静态类型Shape*
Shape*pr = new Rectangle;//静态类型Shape*
在本例中,ps,pc,pr都被声明为Shape*类型的,所以它们的静态类型都是Shape*。注意:无论它们真正指向什么,它们的静态类型都是Shape*.
所谓的对象的动态类型是指“当前所指对象的类型”。也就是说,动态类型可以表现出一个对象将会有什么行为。根据上面的例子,pc的动态类型是Circle*,pr的动态类型是Rectangle*。ps没有动态类型,因为它没有指向任何对象。
动态类型一如其名所示,可以在执行过程中改变(通常是经过赋值运算):
ps=pc; \\ps的动态类型如今是Circle*
ps=pr; \\ps的动态类型如今是Rectangle*
Virtual函数系动态绑定而来,意思是调用一个virtual函数的时候,究竟调用的是哪一个函数代码,取决于发出调用的那个对象的动态类型。
ps->draw(); \\调用的是Rectangle::draw(Red)