虚函数规则详解:
定义:
虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,是C++多态的一种表现。
作用:
实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型,以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。当程序发现虚函数名前的关键virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。
使用方法:
动态绑定指出,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式:
指向基类的指针变量名->虚函数名(实参表)
或
基类对象的引用名. 虚函数名(实参表)
什么函数不能声明为虚函数:
1.构造函数不能声明为虚函数 :
因为在执行构造函数时类对象还未完成建立过程,更谈不上把函数与类对象的绑定(关于绑定可参考上一篇博文)因为构造函数本来就是为了明确初始化对象成员才产生的,然而virtual function主要是为了再不完全了解细节的情况下也能正确处理对象。
2.静态成员函数不能声明为虚函数
(1)静态成员函数并不是“成员”,它没有this指针。
(2)静态成员函数对每个类只有一份代码而且是共享的,所以它不被继承,当然也不能被声明为虚函数。
(3)静态成员函数是静态的在编译时,而虚函数是动态的在运行时。两者创建时间不同。
(4)静态成员函数可以通过类调用,但不能通过对象调用,而虚函数只能通过对象调用才有意义。
3.友元函数不能声明为虚函数
和静态成员类似,它不是成员,不能被继承
4.赋值运算符重载函数最好不要声明为虚函数
5.析构函数可以声明为虚函数
因为无论指针值指的是同一个类中的哪个类对象,系统都会采用动态绑定,调用相应类的析构函数对该对象进行清理。而且继承时最好将析构函数声明为虚函数。
6.普通函数不声明为虚函数
普通函数(非成员函数)声明为虚函数也没有什么意思,因此编译器会在编译时邦定函数。多态的运行期行为体现在虚函数上,虚函数通过继承方式来体现出多态作用,顶层函数不属于成员函数,是不能被继承的。
7.内联函数不能声明为虚函数
其实很简单,内联函数就是为了在代码中直接展开,减少函数调用花费的代价,虚函数是为了在继承后对象能够准确的执行自己的动作,这是不可能统一的。再者内联函数和虚函数有着本质的区别,内联函数是在程序被编译时就展开,在函数调用处用整个函数体去替换,而虚函数是在运行期才能够确定如何去调用的,因而内联函数体现的是一种编译期机制,虚函数体现的是一种运行期机制。此外,一切虚函数都不可能是内联函数。
8:存在多态时析构函数声明为虚函数:
这样写的作用是:在实现多态的时候,当用基类指针操作派生类,在析构的时候,防止只析构基类资源而没有对派生类对象进行析构。