C++虚析构函数
多态也会存在一些问题
我们在释放内存的时候 如果释放的是父类的指针 那只会执行父类的析构函数~如果释放的时候子类的指针那既会执行父类的析构函数也会执行子类的析构函数 这样的话子类的空间如果申请了那会内存泄漏~
比如上面一篇中
在这里面我们就没有释放Circle的空间,如果代码改进加入virtual 执行效果如下
virtual如此好用~但是他也会有一些限制
1、不能修饰普通函数
2、不能修饰全局函数
3、不能修饰内联函数
4、不能修饰构造函数
下面给出虚析构函数的例子
#include <iostream>
using namespace std;
class Shape
{
public:
Shape()
{
cout<<"Shape()"<<endl;
}
virtual ~Shape()
{
cout<<"~Shape()"<<endl;
}
virtual double calcArea()
{
cout<<"Shape-->calcArea"<<endl;
return 0;
}
};
class Coordinate
{
public:
Coordinate(int x,int y)
{
cout<<"Coordinate"<<endl;
m_iX=x;
m_iY=y;
}
virtual ~Coordinate()
{
cout<<"~Coordinate()"<<endl;
}
private:
int m_iX;
int m_iY;
};
class Circle: public Shape
{
public:
Circle(double r)
{
cout<<"Circle()"<<endl;
m_dR=r;
m_pCenter=new Coordinate(3,5);
}
virtual ~Circle()//如果不写virtual系统会自动加上
{
cout<<"~Circle()"<<endl;
delete m_pCenter;
m_pCenter=NULL;
}
virtual double calcArea()
{
cout<<"Circle-->calcArea"<<endl;
return 3.14*m_dR*m_dR;
}
private:
double m_dR;
Coordinate *m_pCenter;
};
class Rect:public Shape
{
public:
Rect(double width,double height)
{
cout<<"Rect()"<<endl;
m_dWidth=width;
m_dHeight=height;
}
virtual ~Rect()
{
cout<<"~Rect()"<<endl;
}
virtual double calcArea()
{
cout<<"Rect-->calcArea"<<endl;
return m_dWidth*m_dHeight;
}
private:
double m_dWidth;
double m_dHeight;
};
int main()
{
Shape *shape1=new Circle(5);
Shape *shape2=new Rect(3,6);
cout<<shape1->calcArea()<<endl;
cout<<shape2->calcArea()<<endl;
delete shape1;
shape1=NULL;
delete shape2;
shape2=NULL;
system("pause");
return 0;
}
下面我们就来讲一下原理~
指针不只可以指向一个对象 也可以指向一个函数 当指针指向一个函数的时候 指针会保存函数入口的地址 然后一直执行下去
对我们的对象来说 实例化一个对象指针的时候会有一个虚函数表 虚函数表里存着指向计算面积函数的入口 所以能正确的找到计算面积函数入口 能正确的执行函数
下面是Circle没有定义自己计算面积的函数的时候的地址
下面是Circle定义自己计算面积的函数的时候的地址,也就是覆盖