I have read that one must not store std::auto_ptr in std::vector and that boost::ptr_vector could be used instead. I have been able to do so, I don’t know however how to use ptr_vector, when I don’t want to store pointers, but a struct, which has a pointer member.
In this example, I want to open some files and store the associated ofstream object with some additional data, for later use. I would like to replace the file field of struct data with a smart pointer. Since the vector<data> v should be the owner, I think that a shared_ptr would work, but wouldn’t be appropriate.
What should I replace the naked pointer file with?
#include <iostream>
#include <fstream>
#include <vector>
struct data {
std::string filename;
std::ofstream* file;
data(const std::string filename, std::ofstream* file)
: filename(filename), file(file)
{
}
};
std::vector<data> open_files()
{
std::vector<data> v;
v.push_back(data("foo", new std::ofstream("foo")));
return v;
}
int main()
{
std::vector<data> v = open_files();
/* use the files */
*(v[0].file) << "foo";
delete v[0].file; // either rely on dtor to close(), or call it manually
}
Update:
I feel I have done a sub optimal job in describing my problem, let me try with another example. Also I am looking for a C++03 solution:
#include <memory>
#include <vector>
#include <boost/ptr_container/ptr_vector.hpp>
struct T {
std::auto_ptr<int> a;
};
int main()
{
// instead of
// std::vector<std::auto_ptr<int> > v;
// use
boost::ptr_vector<int> v;
// what to use instead of
// std::vector<T> w;
}
Concerning your data class, I would suggest using an
std::unique_ptr<std::ofstream>. This is not to save you from an accidental memory leak, since you are deleting the pointer in the constructor, but rather to make the ownership explicit. A user of your code would have to know whatdatais doing with the pointer it takes in the constructor:However, with
unique_ptrthe intend is clear, hence it is harder to make mistakes: