虚函数是为了 实现动态绑定 ,不能声明为虚函数的有 :
1、静态成员函数;2、类外的普通函数;3、构造函数;4、友元函数
此外,还有一些函数可以声明为虚函数,但是没有意义,但编译器不会报错,如:
1、 赋值运算符的重载成员函数:因 为复制操作符的重载函数往往要求形参与类本身的类型一致才能实现函数功能,故形参类型往往是基类的类型,因此即使声明为虚函数,也把虚函数当普通基类普通函数使用。
2、 内联函数: 内联函数目的是在代码中直接展开(编译期),而虚函数是为了继承后能动态绑定执行自己的动作(动态绑定),因此本质是矛盾的,因此即使内联函数声明为虚函数,编译器遇到这种情况是不会进行inline展开的,而是当作普通函数来处理。因此声明了虚函数不能实现内敛的,即内敛函数可以声明为虚函数,但是毫无了内联的意义
1)普通函数(非成员函数)只能overload(重载),不能被override(覆盖),不能被声明为虚函数,因此,编译器会在编译时绑定函数。
2)静态成员函数不能是虚函数,因为静态成员函数对于每个类来说只有一份代码,所有的对象都共享这一份代码,它不归某个对象所有,所以,它也没有动态绑定的必要性。
3)内联成员函数不能是虚函数,因为内联函数本身就是为了在代码中直接展开,减少函数调用花费的代价而设立的,而虚函数是为了在继承后对象能够准确地执行自己的动作,这是不可能统一的。再说,inline函数在编译时被展开,虚函数在运行时才能动态地绑定函数。
4)构造函数之所以不能是虚函数,因为构造函数本来是为了明确初始化对象成员才产生的,然而虚函数主要是为了在不完全了解细节的情况下也能正确处理对象。另外,虚函数是在不同类型的对象产生不同的动作,现在对象还没有产生,如何使用虚函数来完成你想完成的动作?
5)友元函数。C++语言不支持友元函数的继承,对于没有继承特性的函数没有虚函数的说法。友元函数不属于类的成员函数,不能被继承。所以,友元函数不能是虚函数。
虚函数允许函数重写,具体实现时通过对象的虚表(虚函数指针数组,成员变量)实现,而静态成员函数不依赖对象实现,不存在成员变量,因此不能是虚函数。简单的说静态成员函数没有this指针,所以没有虚表,不能实现虚函数的功能,因此不能是虚函数。