2

std::auto_ptr保存してはstd::vectorならず、boost::ptr_vector代わりに使用できることを読みました。ptr_vector私はそうすることができましたが、ポインターを格納したくない場合にを使用する方法がわかりませんが、ポインターメンバーを持つ構造体です。

この例では、いくつかのファイルを開き、関連付けられたofstreamオブジェクトをいくつかの追加データと共に保存して、後で使用できるようにします。fileのフィールドをstruct dataスマートポインターに置き換えたいと思います。は所有者でなければならないので、vector<data> va は機能すると思いますが、shared_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

メンバーとして 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 に答える
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 に答える