2016-08-25 8 views
-2

私は別のサイトで少しのコードを見ました。私は何が起こっているのかについて微妙に考えています。 C++のベクトル初期化:この構文を使用して実際に何が行われていますか?

は文字通りベクトルが「」作成されたときに何が起こっているか、後で

void other(int nx, in ny, int nz) { 
    … 
    vector<float> A(initvec (nx, ny, nz)); 
    … 
} 

私がするように明確ではないよベクトル

vector<float> initvec (int nx, int ny, int nz) { 
    vector<float> data; 
    for (int i = 0; i < nx * ny *nz; ++i){ // assign data elements with sequential values from 0 to nx*ny*nz-1} 
    return data; 
} 

を初期化する関数を考えてみましょう。それは少なくとも不必要なメモリの重複のように思えます。

+2

'data <<(float)i;'はコンパイルすべきではありません。あなたは何か特別なことをするためにオーバーロードされた '<<'を持っていますか? – NathanOliver

+0

[コンパイルしない](http://ideone.com/RHO18j) – PaulMcKenzie

+1

これはすべてここでよく説明されています(http://en.cppreference.com/w/cpp/container/vector) –

答えて

1

initvec関数の結果をコンストラクタを呼び出す代わりにA変数に代入しないのはなぜかと思います。

実際、C++では問題ありません。あなたは、不必要なコピーが続いていると思いますが、そうではありません。 vectorは実際にはクラスなので、C#やJavaなどの言語での振る舞いは、A変数に代入するときに返された参照を単純にコピーすることになります。

C++には移動のセマンティクスがあります。つまり、このシナリオではメモリが再利用されることを意味します。 initvecでは、dataがスタックに割り当てられ、return文に沿ってコピーされました。その後、このメモリはvectorクラスの移動コンストラクタによって再利用されました。

dataの参照はスタックに割り当てられているため、返されませんでした(返されたメモリの割り当てを避ける)。関数のアドレスをローカル変数に残すと、もはや有効ではなくなります。しかし、new operatorのヒープにこのベクトルを割り当てることも、スマートポインタを使ってそれを返すこともできます。これは私が以前言及した言語の振る舞いを模倣するでしょう。前者の場合は、initvecのユーザーが割り当てられたメモリを解放することを信頼することに注意してください。

関連する問題