2

我已经读过,一个不能存储std::auto_ptrstd::vector可以boost::ptr_vector代替使用。我已经能够这样做,但是ptr_vector当我不想存储指针时,我不知道如何使用,而是存储一个具有指针成员的结构。

在此示例中,我想打开一些文件并将关联的ofstream对象与一些附加数据一起存储,以供以后使用。我想用智能指针替换file字段。struct data由于vector<data> v应该是所有者,我认为 ashared_ptr会起作用,但不合适。

我应该用什么替换裸指针file

#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
}

更新: 我觉得我在描述我的问题方面做得不够好,让我试试另一个例子。我也在寻找 C++03 解决方案:

#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;
}
4

3 回答 3

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) { /*  */ } 
于 2012-11-13T13:20:30.507 回答
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包装该指针,但在您的情况下它是不必要的。

于 2012-11-13T12:55:50.880 回答
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);
}
于 2012-11-13T13:58:55.517 回答