How to delete a pointer belonging to an object stored in a vector?

Viewed 73

I have a Containing class, a Contained class, and a Data class. That Containing class holds a vector of Contained objects. The Contained class holds a pointer to a data object, allocated on the heap in Contained's constructor. However, I can't deallocate it in the destructor, since the vector will create copies of Contained and then destroy them, thus destroying the data pointer even in the copy we're using.

TL;DR Here's some code to explain:

class Data {
    public:
        Data();
};

class Contained {
    private:
        Data* data;
    public:
        Contained();
        // what should I add ? a copy constructor ? an assignement operator ? and how
};

class Container {
    private:
        vector<Contained> rooms;
    public:
        //some member functions
};
Contained::Contained() {
    data = new Data();
}

Where do I delete data ?

1 Answers

Using RAII(Resource Acquisition is Initialization)

Add a destructor to the Contained class:

Contained::~Contained() {
    delete data;
}

This will ensure whenever your contained object goes out of scope, it will automatically delete the data pointer it has. So if you do

//delete first element
rooms.erase(rooms.begin());

data ptr of that object will automatically be deleted.

Using smart pointers

Use std::unique_ptr<T>.

class Contained {
    private:
        std::unique_ptr<Data> data;
    public:
        Contained();
        // what should I add ? a copy constructor ? an assignement operator ? and how
};

and in the constructor:

Contained::Contained() {
    data = std::make_unique<Data>();
}

Using smart pointers i.e., (unique_ptr, shared_ptr) ensures your pointer will automatically delete when no one is owning it. Since you can not copy unique_ptr but only move it, you should define a move constructor and move assignment operator on the Contained class.

Contained::Contained(Contained&& other) 
    : data(std::move(other.data))
{}

Contained& operator=(Contained&& rhs) {
    if (this != &other) {
        data = std::move(rhs.data);
    }
    return *this;
}
Related