防止内存泄露
子类继承父类后,在子类构造函数里,通过new 来生成一个对象实例
在析构函数里执行释放内存操作,如果父类不加上virtual 关键词
则子类执行的是父类的析构函数,不执行自己的析构函数。
父类不加virtual 子类继承后,并执行析构函数:
#include <iostream> /** * C++多态 虚析构函数 (防止内存泄露) */ using namespace std; //形状 class Shape { public: Shape(); ~Shape(); virtual double calcArea(); }; class Coordinate { public: Coordinate(int x, int y); ~Coordinate(); protected: int m_iX; int m_iY; }; //Circle继承Shape class Circle : public Shape { public: Circle(double r); ~Circle(); double calcArea(); protected: double m_dR; Coordinate *coordinate; protected: string m_strName; }; //Rect继承Shape class Rect : public Shape { public: Rect(double width, double height); ~Rect(); double calcArea(); protected: double m_dWidth; double m_dHeight; }; Coordinate::Coordinate(int x, int y) { cout << "Coordinate()" << endl; m_iX = x; m_iY = y; } Coordinate::~Coordinate() { cout << "~Coordinate()" << endl; } Rect::Rect(double width, double height) { m_dHeight = height; m_dWidth = width; cout << "Rect::Rect()" << endl; } double Rect::calcArea() { cout << "Rect::calcArea()" << endl; return m_dWidth * m_dHeight; } Rect::~Rect() { cout << "~Rect()" << endl; } Circle::Circle(double r) { m_dR = r; coordinate=new Coordinate(5,5); cout << "Circle()" << endl; } double Circle::calcArea() { cout << "Circle::calcArea()" << endl; return 3.14 * m_dR * m_dR; } Circle::~Circle() { delete(coordinate);//释放内存 cout << "~Circle()" << endl; } Shape::Shape() { cout << "Shape()" << endl; } Shape::~Shape() { cout << "~Shape()" << endl; } double Shape::calcArea() { cout << "Shape::clacArea()" << endl; } int main() { Shape *shape = new Rect(3, 6); Shape *shape1 = new Circle(5); shape->calcArea(); shape1->calcArea(); delete (shape); //释放内存 delete (shape1);//释放内存 return 0; }
输出结果:
Shape() Rect::Rect() Shape() Coordinate() Circle() Rect::calcArea() Circle::calcArea() ~Shape() //父类析构被执行了两次 ~Shape() //父类析构被执行了两次
父类加上virtual关键词后,子类执行析构函数:
class Shape { public: Shape(); virtual ~Shape(); //父类加上virtual virtual double calcArea(); };
输出结果:
Shape() Rect::Rect() Shape() Coordinate() Circle() Rect::calcArea() Circle::calcArea() ~Rect() //子类析构函数被执行 ~Shape() ~Coordinate() //子类析构函数被执行 ~Circle() //子类析构函数被执行 ~Shape()
virtual关键词限制
1.普通函数不能被修饰(类外面单独提供的方法)
2.静态成员不能被修饰
3.内联函数不能被修饰(会导致内联函数失效)