通过声明类的一个或者多个virtual函数为纯虚函数,可以使一个类成为抽象类。抽象类可以为具体的类提供继承基类的作用,通过继承关系达到减少代码量,综合对象特征属性的目的。
一个纯虚函数在声明时“初始化为0”的函数,如下所示:
virtual void fun() const=0;
其中"=0"为纯虚指示符。纯虚函数不提供函数的具体实现,每个派生的具体类必须重写所有基类的纯虚函数的定义,提供函数的具体实现。
#include<iostream>
using namespace std;
class A{
public:
virtual void fun()=0;
};
class B: public A{
public:
void fun(){cout<<"fun B"<<endl;}
};
int main(){
//A *a=new A();
//a->fun(); error 纯虚函数不能实例化
B *b=new B();
b->fun(); // fun B
A *c=new B();
c->fun(); //fun A 转型为基类后调用基类的函数
return 0;
}
虚函数与纯虚函数的区别为:虚函数有函数的具体实现,并且提供派生类是否重写这些函数的选择权。相反,纯虚函数并不提供函数的实现,需要派生类重写来成为具体类,否则派生类仍未抽象类。C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。
本文主要通过一些具体事例演示虚函数在继承函数之中的应用情况:
普通函数:
#include<iostream>
using namespace std;
class A{
public:
void fun(){cout<<"fun A"<<endl;}
};
class B: public A{
public:
void fun(){cout<<"fun B"<<endl;}
};
int main(){
A *a=new A();
a->fun(); // fun A
B *b=new B();
b->fun(); // fun B
A *c=new B();
c->fun(); //fun A 转型为基类后调用基类的函数
return 0;
}
虚函数:
#include<iostream>
using namespace std;
class A{
public:
virtual void fun(){cout<<"virtual A"<<endl;}
};
class B: public A{
public:
virtual void fun(){cout<<"virtual B"<<endl;}
};
int main(){
A *a=new A();
a->fun(); //virtual A
B *b=new B();
b->fun(); //virtual B
A *c=new B();
c->fun(); //virtual B转型之后调用派生类函数实现多态性
return 0;
}
派生类为虚函数:
#include<iostream>
using namespace std;
class A{
public:
void fun(){cout<<"fun A"<<endl;}
};
class B: public A{
public:
virtual void fun(){cout<<"virtual B"<<endl;}
};
int main(){
A *a=new A();
a->fun(); //fun A
B *b=new B();
b->fun(); //virtual B
A *c=new B();
c->fun(); //fun A转型之后调用已经得到实现的实例
return 0;
}
虚析构函数:
#include<iostream>
using namespace std;
class A{
public:
virtual ~A(){cout<<"virtual A"<<endl;}
};
class B: public A{
public:
virtual ~B(){cout<<"virtual B"<<endl;}
};
int main(){
A *a=new A();
delete a; //virtual A
B *b=new B();
delete b; //virtual B
//virtual A
A *c=new B();
delete c; //virtual B
//virtual A
return 0;
}
若析构函数没有虚化,则delete c的结果只有virtual A,也就是说B的析构函数没有被调用一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏。我想所有的C++程序员都知道这样的危险性。
虚函数限制总结:
1.虚函数仅适用于有继承关系的类对象,所以只有类的成员函数才能说明为虚函数.
2.静态成员函数不能是虚函数(构造函数不能是虚函数)
3.内联函数不能是虚函数.
4构造函数不能是虚函数.
5.析构函数可以是虚函数.
简单点说,抽象方法是需要子类去实现的.虚方法,是已经实现了,子类可以去覆盖,也可以不覆盖取决于需求.