文件流,STL容器和可变长度数组

时间:2013-02-06 07:52:33

标签: c++ stl ofstream

最初,我有一些看起来像

的代码
class Ball
{
public:
    double x , y ;
    ofstream out ;
} ;

int main()
{
    Ball array[N] ;

    array[0].out.open("./position_1.txt") ;
    array[1].out.open("./position_2.txt") ;

    ......
}

其中N是运行时确定的常数。 但它最近遇到了可变长度数组问题。

我尝试使用STL容器来关注此帖Can't set variable length with variable的建议。

int main()
{
    vector<Ball> Balls ;
    Ball b ;

    b.out.open( "./position_1.txt" ) ;
    Balls.push_back( b ) ;
    ......
}

它在push_bak()失败,因为无法复制流。

我无法在运行之前确定球的数量,我必须存储文件流而不是路径以提高效率(防止打开和关闭文件)。

有没有办法实现这个目标? 感谢

3 个答案:

答案 0 :(得分:3)

C ++流不可复制,但它们是可移动的,所以你可以这样做:

Balls.push_back( std::move(b) );

//DO NOT use b after push_back, as it has been moved!

并且编译器为您的类生成的默认移动语义可以正常工作。

在C ++ 11中,您可以这样写:

std::vector<Ball> balls(N); //N is known at runtime

balls[i].out.open( "./position_1.txt" ); //i <= i < N

请注意,这在C ++ 03中不起作用,因为在C ++ 03中,vector的构造函数会创建类型为Ball的默认创建对象的N 副本。但是,在C ++ 11中,它不会复制任何内容!

答案 1 :(得分:1)

如果您的编译器/库足够大,以至于它们不支持流的移动语义(许多不支持),您可以考虑将(智能)指针存储到结构中的流中。你可能希望它成为一个智能指针 - 你自己正确处理所有权转移可能需要做很多工作才能做好。

答案 2 :(得分:0)

然后让Balls成为Ball的指针向量。用new和push_back指定Ball对象。

请注意,如果使用简单指针,则必须使用循环删除末尾的Ball对象。您可以使用智能指针来避免这种情况,例如std::tr1::shared_ptr