虚函数为了重写和多态的需要,在基类中是有定义的,即便定义是空,所以子类中可以重写也可以不写基类中的此函数!
纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数!
1、动态绑定
在执行期间(非编译期)判断所引用对象的实际类型,根据实际类型(动态类型)调用相应的方法。
动态绑定灵活性相对静态绑定来说要高,因为它在运行之前可以进行选择性的绑定,但同时,动态绑定的执行效率要低些,因为绑定对象还要进行编译(现在编译期一般都会多次编译)。
触发动态绑定的条件:(1)只有指定为虚函数的成员函数才能进行动态绑定;(2)只有通过基类的指针或引用进行函数调用。
2、虚函数
基类通常应将派生类需要重定义的任意函数定义为虚函数。
class Base
{
public:
virtual void print()
{
cout<<"Base::print"<<endl;
}
};
class Derived:public Base
{
public:
virtual void print()
{
cout<<"Derived::print"<<endl;
}
};
void main()
{
Base* ptr=new Derived();
ptr->print(); //ptr的动态类型是Derived,静态类型是Base
delete ptr;
}
一旦函数在基类中声明为虚函数,它就一直为虚函数,派生类无法改变该函数为虚函数这一事实。
如果去掉print()前面的irtual,代码输出为:
没有发生动态绑定。
3、虚函数的实现机理
详见:http://blog.csdn.net/haoel/article/details/1948051
4、纯虚函数
在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该类的派生类去做(派生类必须要实现)。在基类中实现纯虚函数的方法是在函数原型后加“=0”。声明形式:virtual void fun()=0;
引入原因:1)为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。2)在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
抽象类:含有一个或者多个纯虚函数的类是抽象类,抽象类不能创建对象。而只有被继承,并重写其虚函数后,才能使用。