5

这是我的问题,我需要创建 X 个文件并根据不同的事实写入它们,我的解决方案是创建一个像这样的 ofstream 指针向量

#include <boost/algorithm/string.hpp>
#include <vector>
#include<string>
#include <iostream>
#include <fstream>
vector<ofstream*> files;
files.resize(SplitVec.size()-4);
          for(i=0;i<SplitVec.size()-4;i++)
          {
              line="/Users/jorge/Desktop/testing/strain_"+lexical_cast<string>(i);
              cout<<"ine"<<endl;
              files[i]=new ofstream(line.c_str());
          }

直到这部分它创建了很好的文件,然后在我写给它们的程序中,这也很好,我的问题是当我想关闭对象时,如果我使用:

for(i=0;i<SplitVec.size()-4;i++)
          {
              *files[i].close();
          }

我收到以下错误:

In file included from main.cpp:14:./methyl.h:298: error: request for member 'close' in 'files. std::vector<_Tp, _Alloc>::operator[] [with _Tp = std::ofstream*, _Alloc = std::allocator<std::ofstream*>](1ul)', which is of non-class type 'std::ofstream*'

所以,我有一个问题,首先,为什么我不能调用 close,它是一个指向 ofstream 的指针,所以使用 *files[i],我会想象我可以关闭它,其次,如果我不关闭它,程序工作正常,但我几乎可以肯定这是一种不好的做法,并且不想成为一个懒惰或蹩脚的程序员,我已经尽可能多地看了,但我找不到答案。谢谢!!!

4

2 回答 2

9

采用

(*files[i]).close();

或直接

files[i]->close();
于 2012-09-20T09:32:56.853 回答
5

您的代码不是异常安全的(例如,如果抛出异常,因为您有一个原始指针向量,它们会被泄露- 带有关联的流句柄)。

我建议采用现代 C++ RAII 方法。

例如,如果您使用类似shared_ptr(来自 Boost,或来自 C++11<memory>标头)的智能指针,您可以构建一个vectorof shared_ptr,并使用它make_shared来分配ofstream对象:

// RAII exception-safe approach
vector<shared_ptr<ofstream>> files;

// Add a new ofstream object to the vector:
files.push_back( make_shared<ofstream>( filename ) );

当向量超出范围时,它会被破坏,并且所有指向的流对象都会自动释放:非常简单、清晰且异常安全。

如果你想在向量超出范围之前强制流清理,你可以.clear()在向量上调用方法。

(另一种方法是使用 C++11 move-semantics -powered unique_ptr,并定义 a vector<unique_ptr<ofstream>>,但不幸的是没有标准等效make_sharedfor unique_ptr,并且代码可能有点冗长,除非您编写自定义实现make_unique,例如Herb Sutter 提出的那个。)

请注意,通常的files[i]->close()语法也适用于这种智能指针向量的情况。

于 2012-09-20T09:58:34.230 回答