1

もともと、次のようなコードがあります

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コンテナーを使用して変数で変数の長さを設定できません。

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

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

push_bak()ストリームをコピーできないため、で失敗します。

実行前にボールの数を判断できず、効率のためにパスではなくファイルストリームを保存する必要があります (ファイルの開閉を防ぎます)。

目標を達成する方法はありますか?ありがとう

4

3 に答える 3

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 のコンストラクターがtype のデフォルトで作成されたオブジェクトのN 個のコピーBallを作成するためです。ただし、C++11 では、コピーは作成されません。

于 2013-02-06T07:55:52.107 に答える
1

コンパイラ/ライブラリが十分に古く、ストリームの移動セマンティクスをまだサポートしていない場合 (多くはサポートしていません)、代わりにストリームへの (スマート) ポインタを構造体に格納することを検討してください。ただし、おそらくそれをスマートなポインターにしたいと思うでしょう。所有権の譲渡を自分で正しく処理するには、かなりの作業が必要になる可能性があります。

于 2013-02-06T08:02:23.707 に答える
0

次に、Balls を Ball へのポインターのベクトルにします。Ball オブジェクトを new で割り当て、ポインタを push_back します。

単純なポインターを使用する場合は、ループの最後にある Ball オブジェクトを削除する必要があることに注意してください。などのスマート ポインターを使用すると、これを回避できますstd::tr1::shared_ptr

于 2013-02-06T08:04:23.950 に答える