値またはC ++での参照によって関数にベクトルが渡される


94

私はC ++でコーディングしています。関数がvoid foo(vector<int> test)あり、それをプログラムで呼び出す場合、ベクトルは値または参照で渡されますか?ベクトルと配列が似ており、関数like void bar(int test[])が値ではなく参照(ポインタ?)でテストに合格することを知っているので、確信が持てません。私の推測では、値による受け渡しを避けたい場合は、ポインター/参照によって明示的にベクトルを渡す必要がありますが、確信が持てません。


5
C ++には「値渡し」のセマンティクスがあるため、値渡しされます。参照渡しすることもできます。どちらを選択するかは、実際には関数の機能によって異なります。
juanchopanza 2014年

2
参照によって使用します。ベクトルの内容を変更する関数でconstにしたくない場合は、参照で渡すだけです。
不要で

3
また、参照はポインタではありません。
常磁性クロワッサン2014年

2
@AliKazmi関数の本体にコピーが必要な場合を除きます。
juanchopanza 2014年

それはあなたが達成したいことに依存します。たとえば、所有権を渡したい場合は、unique_ptrを使用して、標準のスマートポインターの1つを使用すると便利な場合があります。しかし、通常は、参照によりstd :: vectorを渡します。
ErikAlapää2014年

回答:


134

推測しなければならないのであれば、あなたはJavaの出身だと思います。これはC ++であり、特に&-operator を使用して指定しない限り、値によって渡されます(この演算子は「address-of」演算子としても使用されますが、コンテキストが異なります)。これはすべて十分に文書化されていますが、とにかく繰り返します。

void foo(vector<int> bar); // by value
void foo(vector<int> &bar); // by reference (non-const, so modifiable inside foo)
void foo(vector<int> const &bar); // by const-reference

ベクトル(void foo(vector<int> *bar))へのポインターを渡すこともできますが、何をしているのかがわからず、これが本当に正しい方法であると思わない限り、これを行わないでください。

また、ベクトルがあるではない配列と同じ!内部的に、ベクターはメモリ管理を処理する配列を追跡しますが、他の多くのSTLコンテナーも追跡します。ポインターまたは配列を期待する関数にベクトルを渡すことはできません。その逆も同様です(基礎となる配列への(ポインターへの)アクセスを取得してこれを使用することはできます)。ベクトルはメンバー関数を通じて多くの機能を提供するクラスですが、ポインターと配列は組み込み型です。また、ベクトルは動的に割り当てられます(つまり、サイズは実行時に決定および変更される可能性があります)。一方、Cスタイルの配列は静的に割り当てられます(そのサイズは一定であり、コンパイル時に認識される必要があります)。その使用は制限されます。

C ++全般(特に配列の減衰)についてさらに読んでから、配列とポインタの違いを示す次のプログラムをご覧になることをお勧めします。

void foo1(int *arr) { cout << sizeof(arr) << '\n'; }
void foo2(int arr[]) { cout << sizeof(arr) << '\n'; }
void foo3(int arr[10]) { cout << sizeof(arr) << '\n'; }
void foo4(int (&arr)[10]) { cout << sizeof(arr) << '\n'; }

int main()
{
    int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    foo1(arr);
    foo2(arr);
    foo3(arr);
    foo4(arr);
}

2
誰かが最後の宣言foo4関数を理解するのを手伝ってくれる?他の関数のようにポインターのサイズではなく配列のサイズを返すのはなぜですか?
abhishek_M 2017年

3
@abhishek_Mパラメータタイプは参照であるため。参照は、まったく同じ型の式にのみバインドできます。このため、配列への参照はポインターにバインドできないため、配列は減衰しません。同じタイプの配列(この場合は10の整数の配列)にのみバインドできます
bolov

1
c ++ 11には「移動セマンティクス」があり、それを注意深く実行して、コピーせずに(移動セマンティクスを使用して)値で渡すことができます。ここに私を大いに助けたリンクがあります:mbevin.wordpress.com/2012/11/20/move-semantics
fchen

23

A vectorは配列と機能的に同じです。しかし、言語にvectorは型intがあり、型でもあります。関数の引数に対して、任意の型(を含むvector[])の配列はポインターとして扱われます。A vector<int>int[](コンパイラにとって)同じではありません。vector<int>配列でも参照でもポインタでもない-値で渡されるため、copy-constructorを呼び出します。

そのため、参照として渡すにはvector<int>&const関数で変更されていない場合は、を使用することが望ましい)を使用する必要があります。


関数を参照して「ベクトルの配列」を渡すための構文は何ですか?
ab123 2017年

void functionName(std :: vector <int>(&vc)[5]){}
RIanGillis

9

void foo(vector<int> test)

ベクトルはこれで値によって渡されます。

あなたは文脈に応じてベクトルを渡すより多くの方法があります:-

1)参照渡し:-これにより、関数fooはベクトルの内容を変更できます。ベクトルのコピーが回避されるため、値渡しよりも効率的です。

2)const-referenceで渡す:-これは、ベクトルの内容を関数で変更したくない場合に効率的で信頼性があります。


1

引数として関数内のベクトルを値で渡すと、単純にベクトルのコピーが作成され、その特定の関数を呼び出したときに、メイン関数で定義されているベクトルに影響はありません。一方、特定の関数に記述されているものをすべて参照渡しでベクトルを渡す場合、その特定の関数を呼び出すと、すべてのアクションがメイン関数または他の関数で定義されているベクトルに対して実行されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.