aurora
aurora

Reputation: 67

What should be included in the destructor in C++

Here is two sample classes and the implementation of destructor for class Foo. Why is m_barvec1 implemented as the way it is in the destructor and what does vector<Bar *> m_barvec1 mean?

class Bar { 
public:
    Bar() : m_arr(new int[100]) {} 
    ~Bar();
    int m_x;
    std::list<int> m_list;
    int* m_arr; 
};

class Foo { 
public:
    Foo() : m_barvec3(new std::vector<Bar>()) {} 
    ~Foo();
    Bar m_bar; 
    std::vector<Bar *> m_barvec1; 
    std::vector<Bar> m_barvec2;
    std::vector<Bar> *m_barvec3;
};

Foo::~Foo() {
    for (size_t i = 0; i < m_barvec1.size(); i++) {
        delete m_barvec1[i];
    }
    delete m_barvec3;
}

Upvotes: 1

Views: 90

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596287

m_barvec1 is a std::vector object holding raw pointers to Bar objects. The Foo destructor is destroying every Bar object being pointed at by the std::vector. A better way to handle this is to use std::unique_ptr<Bar> or std::shared_ptr<Bar> instead of Bar* for the std::vector's element type, let std::unique_ptr/std::shared_ptr destroy the Bar objects automatically.

m_barvec2 is a std::vector object holding Bar objects. The std::vector's destructor will handle destroying the Bar objects, so there is no user code needed in Foo's destructor to handle this.

m_barvec3 is a pointer to a std::vector object that holds Bar objects. The Foo destructor is destroying the std::vector being pointed at, which in turn will destroy the Bar objects it holds. A better way to handle this is to use std::unique_ptr<std::vector<Bar>> instead of std::vector<Bar>* for the pointer, let std::unique_ptr destroy the std::vector automatically.

Using smart pointers for m_barvec1 and m_barvec3 would allow Foo's destructor to then be removed completely.

Upvotes: 1

Related Questions