1.虚函数可以用来实现动态函数绑定,子类和基类重载的函数在调用的时候可以对应各自对象的实现。
例如:
#include<iostream>
using namespace std;
class C
{
public:
C(){
cout<<"C creator is using"<<endl;
}
virtual string toString(){
return "this is C class";
}
virtual ~C(){
cout<<"output memory of C"<<endl;
}
};
class B:public C
{
public:
B(){
cout<<"B creator is using"<<endl;
}
string toString(){
return "this is B class";
}
~B(){
cout<<"output memory of B"<<endl;
}
};
class A:public B{
public:
A(){
cout<<"A creator is using"<<endl;
}
string toString(){
return "this is A class";
}
~A(){
cout<<"output memory of A"<<endl;
}
};
void display(C *x){
cout<<x->toString().data()<<endl;
}
int main()
{
C *c = new C();
C *b = new B();
C *a = new A();
display(c);
display(b);
display(a);
system("pause");
return 0;
}
这样就可以分别结果是:
2.纯虚函数可以构建抽象类
3.当用基类声明的对象用子类实例化时(公有继承),那么基类的析构函数必须声明为虚函数,要不然会有内存泄露,子类占的内存并没有释放。
例如:
#include<iostream>
using namespace std;
class C
{
public:
C(){
cout<<"C creator is using"<<endl;
}
virtual string toString(){ return "this is C class"; } ~C(){ cout<<"output memory of C"; }};class B:public C{ public:
B(){
cout<<"B creator is using"<<endl;
}
string toString(){ return "this is B class"; } ~B(){ cout<<"output memory of B"<<endl; } };class A:public B{ public:
A(){
cout<<"A creator is using"<<endl;
}
string toString(){ return "this is A class"; } ~A(){ cout<<"output memory of A"<<endl; }};void display(C *x){ cout<<x->toString().data()<<endl;}int main(){ C *c = new C(); C *b = new B(); C *a = new A(); display(c); display(b); display(a); delete a; system("pause"); return 0;}
delte a的时候结构显示只有基类的析构函数调用了,说明子类并没有从内存中完全释放。
在基类(A)的析构函数前加virtual之后,结果是:
这时对象a所占的内存才完全释放。
注意:这种函数的绑定只适合堆区动态分配的内存,如果只是在函数栈去声明的一个对象,虚函数并不能实现动态绑定。
例如:
int main()
{
//C *c = new C();
//C *b = new B();
C *a = new A();
C mc = A();
//display(c);
//display(b);
display(a);
display(&mc);
delete a;
system("pause");
return 0;
}
具体原因是可以关注下一篇博客。。。