C++ virtual destructor

Preventing Memory leaks

When a subclass inherits from its parent class, in the subclass constructor, new is used to generate an object instance

Perform a memory free operation in the destructor if the parent class does not include the virtual keyword

A subclass executes its parent’s destructor and does not execute its own.

If virtual is not added to the parent class, and the destructor is executed:

#include <iostream>
/** * C++ polymorphic virtual destructor (to prevent memory leaks) */

using namespace std;

/ / shape
class Shape {
public:
    Shape();

    ~Shape();

    virtual double calcArea(a);

};
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(a);

protected:
    double m_dR;
    Coordinate *coordinate;

protected:
    string m_strName;
};

/ / the Rect inheritance hierarchy
class Rect : public Shape {
public:
    Rect(double width, double height);

    ~Rect();

    double calcArea(a);

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);// Free memory
    cout << "~Circle()" << endl;
}

Shape::Shape() {
    cout << "Shape()" << endl;
}

Shape::~Shape() {
    cout << "~Shape()" << endl;
}

double Shape::calcArea() {
    cout << "Shape::clacArea()" << endl;
}


int main(a) {
    Shape *shape = new Rect(3.6);
    Shape *shape1 = new Circle(5);
    shape->calcArea();
    shape1->calcArea();
    delete (shape); // Free memory
    delete (shape1);// Free memory
    return 0;
}
Copy the code

Output result:

Shape() Rect::Rect() Shape() Coordinate() Circle() Rect::calcArea() Circle::calcArea() ~Shape() // Parent destructor is performed twice ~Shape() // The parent destructor was executed twiceCopy the code

After the virtual keyword is added to the parent class, the subclass performs the destructor:

class Shape {
public:
    Shape();

    virtual ~Shape();	// Add virtual to the parent

    virtual double calcArea(a);

};
Copy the code

Output result:

Shape() Rect::Rect() Shape() Coordinate() Circle() Rect::calcArea() Circle::calcArea() ~Rect() // The subclass destructor is executed ~Shape() ~Coordinate() // The subclass destructor is executed ~Circle() // The subclass destructor is executed ~Shape()Copy the code

Virtual keyword restriction

1. Ordinary functions cannot be modified (methods provided separately outside the class)

2. Static members cannot be decorated

3. The inline function cannot be modified (it will invalidate the inline function)