1、构造函数不能是虚函数。因为构造函数不是一个普通的函数,要构造一个对象,构造函数必须掌握所创建的对象的确切类型,因此构造函数不能是虚的。
2、析构函数可以是虚函数。首先我们要搞清楚为什么要虚析构函数?这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。也就是只有当静态类型为基类,而动态类型为子类时,为了确保子类的析构函数能被调用,基类的析构函数必须被声明为虚析构函数。
一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏。当然,如果在析构函数中做了其他工作的话,那你的所有努力也都是白费力气。
当然,并不是要把所有类的析构函数都写成虚函数。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。
3、纯虚函数
声明纯虚函数的方法:
virtual void purefun()=0;
声明一个纯虚函数pure virtual 的目的就是让Derived class只继承函数接口,因为它没有定义。但是实际上是可以有一份Defualt定义的,在使用时需要指出类名。如:
Derived->Base::Purefunction();
注意含有纯虚函数的类是不能被实例化的。如果Base类中有一个纯虚函数purefun(),Derived继承了Base后必须对purefun()进行重写,否则Derived也是一个函数纯虚函数的类,同样是不能被实例化的。
4、virtual函数的缺省参数值是静态绑定的,所以记住决不要重新定义继承而来的virtual 函数的缺省参数值。
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
class Base
{
public:
virtual void display(int i =1)
{
cout<<"Base Display"<<endl;
}
};
class Derived :public Base
{
public:
virtual void display(int i = 2)
{
if(i ==2)
cout<<"derived i==2"<<endl;
if(i == 1)
cout<<"derived i ==1"<<endl;
}
};
int main()
{
Base* p=new Derived();
p->display();
}
输出是"derived i==1"