C++ 虚析构函数

天涯浪子 提交于 2019-12-04 16:27:13

防止内存泄露
子类继承父类后,在子类构造函数里,通过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.内联函数不能被修饰(会导致内联函数失效)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!