我已经读过,不能在std::auto_ptr
中存储std::vector
,而是可以使用boost::ptr_vector
。我已经能够这样做,但我不知道如何使用ptr_vector
,当我不想存储指针,而是一个结构,它有一个指针成员。
在此示例中,我想打开一些文件并将关联的ofstream
对象与一些其他数据一起存储,供以后使用。我想用智能指针替换file
的{{1}}字段。由于struct data
应该是所有者,我认为vector<data> v
可行,但不合适。
我应该用?
替换裸指针shared_ptr
file
更新 我觉得我在描述我的问题时做了一个次优的工作,让我尝试另一个例子。我也在寻找C ++ 03解决方案:
#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
}
答案 0 :(得分:1)
关于您的数据类,我建议您使用std::unique_ptr<std::ofstream>
。这不是为了避免意外的内存泄漏,因为您正在删除构造函数中的指针,而是使所有权显式。您的代码的用户必须知道data
在构造函数中使用指针所做的事情:
std::ofstream ofs;
{
data d1("crash", &ofs);
} // error! d1 will attempt to delete stack allocated object
std::ofstream* pOfs = new std::ofstream(....);
data d2("crash again", pOfs);
delete pOFs; // user thinks data makes a deep copy
然而,unique_ptr
意图很清楚,因此更难犯错误:
data d3("OK", std::unique_ptr<std::ofstream>(new std::ofstream(....)));
std::unique_ptr<std::ofstream> pOfs2(new std::ofstream(....));
data d4("OK", pOfs2); // safe, pOfs's contents have been safely moved
// we can check pOfs2 after the move
if (pOfs2) { /* */ }
答案 1 :(得分:0)
您可以删除析构函数中的指针:
struct data
{
std::string filename;
std::ofstream* file;
data(const std::string filename, std::ofstream* file)
: filename(filename), file(file)
{
}
~data()
{
delete file;
}
};
或者使用std::unique_ptr
来包装该指针,但在你的情况下它是不必要的。
答案 2 :(得分:0)
您不需要将ofstream *作为成员。
#include <iostream>
#include <fstream>
#include <vector>
struct data {
std::string filename;
data(const std::string filename) : filename(filename)
{}
};
std::vector<data> open_files()
{
std::vector<data> v;
v.push_back(data("foo"));
return v;
}
如果要附加到文件,请指定应用程序文件模式。
void print_files(const std::vector<data>& v)
{
for(std::vector<data>::const_iterator it = v.begin(); it != v.end(); ++it)
{
std::ofstream os(it->filename, std::ostream::app);
os << "bar";
}
}
int main()
{
std::vector<data> v = open_files();
print_files(v);
}