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

File stream, STL container, and variable length arrays

本文关键字:数组 STL 文件      更新时间:2023-10-16

最初,我有一些代码看起来像

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是运行时间确定的常数。但是最近它遇到了可变长度数组的问题。

我试图遵循这篇文章的建议Can';t使用STL容器用变量设置可变长度。

int main()
{
    vector<Ball> Balls ;
    Ball b ;
    b.out.open( "./position_1.txt" ) ;
    Balls.push_back( b ) ;
    ......
}

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

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

有什么方法可以实现这个目标吗?感谢

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

Balls.push_back( std::move(b) );
//DO NOT use b after push_back, as it has been moved!

编译器为您的类生成的默认move语义可以很好地处理此问题。

在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中,向量的构造函数会创建类型为Ball的默认创建对象的N个副本。然而,在C++11中,它不会复制任何内容!

如果你的编译器/库足够旧,还不支持流的移动语义(很多都不支持),你可以考虑在结构中存储一个指向流的(智能)指针。不过,你可能确实希望它成为一个聪明的指针——独自正确处理所有权转移可能需要做很多工作。

然后使Balls成为指向Ball的指针向量。为Ball对象分配新的和push_back的指针。

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