不能声明为虚函数的函数
1. 普通函数
普通函数不是类的成员函数,所以只能被重载而不能被重写,声明为虚函数也没有任何的意义。而且编译器会在编译时绑定函数,但动态多态体现在运行时绑定。
2. 静态成员函数
首先静态成员函数不属于任何类对象或类实例,它是所以类对象共享的,所以静态函数变为虚函数没有意义。
其次静态函数中没有this指针,而虚函数依靠虚表指针和虚表来调用,虚表指针在类的构造函数中创建生成并且只能利用this指针来访问,所以静态成员函数不能是虚函数
3. 友元函数
友元函数同样不是类的成员函数,所以不能被继承
4. 内联函数
内联函数是为了减少函数调用的花销而定义的,在编译期间会被展开。而虚函数是在运行时才确定调用的是哪一个函数,两个是冲突的
5. 构造函数
构造函数不能是虚函数主要有下面几个原因:
- 首先虚函数是由虚表指针找到虚表,再根据虚表来调用的。而这个虚表指针存放在对象的前四个字节。如果构造函数是虚函数就需要通过虚表来调用。可是此时对象还没有实例化,也没有内存空间,自然这个虚表指针也就不存在,无法找到虚表。所以构造函数不能是虚函数
- 虚函数的作用在于通过基类的指针或引用来调用它的时候能够变成调用子类的那个成员函数。而构造函数是在创建对象的时候由编译器自动调用的,我们不可能去利用基类的指针或引用去调用,所以也就规定了构造函数不能是虚函数
建议声明为虚函数的函数
析构函数
通常我们建议将析构函数声明为虚函数。
在析构的时候,我们会先调用派生类的析构函数,然后再调用基类的析构函数。假设现在有一个基类的指针指向了派生类,如果我们要删除基类的指针,而且基类的析构函数不定义为虚函数,那么析构的时候会直接调用基类自己的析构函数,派生类的那部分对象就不会被析构而造成内存泄漏