web-dev-qa-db-ja.com

ポインタ渡しと参照渡し

可能性のある複製:
C++のポインター変数と参照変数の違いは何ですか?
C++の参照渡しよりもポインタ渡しの方がメリットはありますか?

どちらの場合でも、私は結果を達成しました。では、一方が他方よりも優先されるのはいつですか?あるものを他のものよりも使用する理由は何ですか?

#include <iostream>
using namespace std;
void swap(int* x, int* y)
{
    int z = *x;
    *x=*y;
    *y=z;
}
void swap(int& x, int& y)
{
    int z = x;
    x=y;
    y=z;
}

int main()
{
    int a = 45;
    int b = 35;
    cout<<"Before Swap\n";
    cout<<"a="<<a<<" b="<<b<<"\n";

    swap(&a,&b);
    cout<<"After Swap with pass by pointer\n";
    cout<<"a="<<a<<" b="<<b<<"\n";

    swap(a,b);
    cout<<"After Swap with pass by reference\n";
    cout<<"a="<<a<<" b="<<b<<"\n";
}

出力

Before Swap
a=45 b=35
After Swap with pass by pointer
a=35 b=45

After Swap with pass by reference
a=45 b=35
41
cppcoder

参照は、意味的に次のとおりです。

T& <=> *(T * const)

const T& <=> *(T const * const)

T&& <=> [no C equivalent](C++ 11)

他の回答と同様に、C++からの次のFAQは1行の回答です。可能な場合は参照、必要な場合はポインター。

ポインターに対する利点は、NULLを渡すために明示的なキャストが必要なことです。それでも可能です。私がテストしたコンパイラーのうち、次のものについて警告を発するものはありません。

int* p() {
    return 0;
}
void x(int& y) {
  y = 1;
}
int main() {
   x(*p());
}
26
moshbear

実際、ほとんどのコンパイラーは、参照が一般にポインターを使用して実装されるため、両方の関数呼び出しに対して同じコードを出力します。

このロジックに従って、(非定数)参照型の引数が関数本体で使用されると、生成されたコードは引数のアドレスで静かに動作し、それを逆参照します。さらに、そのような関数の呼び出しが検出されると、コンパイラーは値をコピーする代わりに引数のアドレスを渡すコードを生成します。

基本的に、参照とポインタはそれほど変わりません実装の観点から主な(そして非常に重要な)違いは哲学にあります:参照はオブジェクトそのものです別の名前で。

参照には、ポインターと比較していくつかの利点があります(たとえば、NULLにはできないため、使用する方が安全です)。したがって、C++を使用できる場合、参照渡しは一般的にエレガントであると見なされ、優先されるはずです。ただし、Cでは参照による受け渡しはありません。したがって、Cコード(または恐ろしいdictu、CとC++コンパイラの両方でコンパイルするコードを作成する場合は、それは良い考えではありませんが)する必要があります。ポインタの使用に制限してください。

6
user529758

ここ は、問題に関する優れた記事です-「可能な場合は参照を使用し、必要な場合はポインターを使用します」。

4
Rocky

Cで「参照」を渡すことができる唯一の方法はポインターによる受け渡しであるため、かなり多く使用されていることがわかります。

NULLポインターは、パラメーターが未使用または無効であることを示すための便利な規則なので、その場合はポインターを使用します。

一度参照を設定すると更新することはできないため、再割り当てが必要な場合はポインターを使用してください。

正当な理由がないすべてのケースで参照を優先します。できればconstにします。

4
Mark Ransom

参照を参照できないNULLを参照する必要がある場合にのみ、常に参照とポインタを使用します。

こちらをご覧くださいFAQ: http://www.parashift.com/c++-faq-lite/references.html#faq-8.6

2
Sanish