2012-04-09 12 views
2

可能な二重に参照し、ポインタを使用するには:
C++: When to use References vs. Pointersなぜ、どこでC++

私はから来ておりますので、私はC/C++言語へのかなり新しいプログラマだと、 C#、Java、JavaScriptの背景とVisual BasicとPythonのちょっとしたことから、私はC++のいくつかのことを理解するのに苦労しています。

私はすでに参照とポインタを使用する方法を知っていると彼らは本当に何を意味する、などしかし、なぜ、どこでそれらを使用するために私は理解していません。私は、参照が時々このように使用されていることを知っている:

int x = 2; 

void Square(int &value) 
{ 
    value = value*value; 
} 

Square(x); 

cout << x << endl; 

、出力は4

になります私はかなりこのように行う、なぜそのように行うために理解していないしていないと思った。

int x = 2; 

int Square(int value) 
{ 
    value = value*value; 
    return value; 
} 

x = Square(x); 

cout << x << endl; 

はとにかく、私は誰かが私がなぜ、どこで参照とポインタを使用することを理解するのに役立つことができるかもしれ願っています。

答えて

3

あなたは2つの主な理由のための参照を渡す:あなた場合は

を渡すオブジェクトをコピーするコストを避けるために、あなたの関数

  • 内で参照オブジェクトの値を変更するには

    • を2番目の利点が欲しいが最初のものではない、あなたは通常、渡されたオブジェクトを間違って変更することを避けるためにconst参照を渡す。C++で

      、ポインタや参照がはるかに2つの例外と同じである:0(またはnullptr)を指すことができない

      • 参照
      • リファレンスは常に同じオブジェクト
      を指していなければなりません

      これらのことのいずれかを実行する場合は、ポインタを使用する必要があります。

      さらに、ポインタは通常、newを使用してヒープで作成されたオブジェクトを指しますが、参照は通常スタック内に作成されたオブジェクトを指します。つまり、ポインターが指すオブジェクトの有効期間は、通常、手動で制御されます。それらを破壊するためにnewによって作成されたオブジェクトに対して明示的にdeleteを呼び出さなければなりませんが、スタックで作成されたオブジェクトの存続期間はランタイムによって自動的に管理されます。

      これはあなたが知る必要があったか、より具体的なものを探しているかわかりません。

  • +0

    ありがとうございました! – UnTraDe

    +2

    C++プログラマーの初めの間違いは、参照を使用できるポインタを使用していることに注意してください。あなたがしなければならない限り、新しくヒープを入れて、ポインタを渡してはいけません(参照を使用しないでください)。 – Ricibob

    +0

    これを念頭に置いておきます。 – UnTraDe

    0

    第2の例では、変数xSquareの関数内にのみ表示されます)をローカルにコピーします。

    あなたのグローバルxが非変わっ滞在することを確認してくださいしたい場合は、そのように行います。しかし、高価な(変数がより大きいオブジェクト/構造体の場合)...と冗長 - キーワードconstをチェックアウトしている可能性があります。参照として

    +0

    ありがとうございます! ちょうど確かに、高価なことは、より多くのメモリを犠牲にすることを意味しますか? – UnTraDe

    +0

    だけでなく、 'CPU'でも – IProblemFactory

    +0

    ありがとう! – UnTraDe

    0

    渡す引数は、あなたがそれのコピーである変数の(あなたはそれにいくつかの操作を行った場合)、その値を変更するつもりはないことを意味します。 &の値を使用しているため、&の値が指すアドレスに格納されている内容が変更されます。

    そして、あなたはSqure(中のxの代わりに&のxを渡す必要があります)。

    したがってX = Squre(& X)。

    又は

    Squre(& X)。

    は同じです。

    +0

    ありがとう! x = Squre(&x);は無効ではありませんか? – UnTraDe

    0

    参照は単なる変数の疑似名です。任意のアクションが参照に適用される実際の影響は、あなたがあなたの例では

    int a = 5; 
    int &b = a; 
    b++; // 'a' gets equal to 6 
    

    参照変数は、あなたは、乗算の結果を返しますが、あなたは何も返さない関数に渡された変数の値を変更するには何が必要な場合は?

    これは参考になる場合です。ポインタは、ポインタが変数の擬似名ではなく、そのアドレスであることを除いて、同様の動作をします。変数へのポインタを関数に渡して参照を外すことができ、まったく同じ方法で変数に影響を与えます。

    +0

    ありがとう! – UnTraDe

    1

    このような例では実際的な違いはありませんが、Square()に整数を渡す代わりに、imagine squareは10ギガバイトのデータを取った複雑なアルゴリズムでした。ポインタを使う方が良いと思わないので、パラメータはコピーされませんか?

    +0

    ありがとうございます!それはメモリ管理にのみ関連していると言いますか? – UnTraDe

    +0

    コンパイラが渡される引数のコピーを作成しないため、単純に高速です。 –

    0

    よく、POD構造の場合、操作=はわかりやすいため、多くの利点はありません。

    だから、あなたのx = square(x)はかなり良いパフォーマンスで、それが言うことをかなり行います。

    オブジェクトをメソッドに渡すと、ポインタ/参照を使用する利点が生じます。この場合:

    Object x; 
    
    Object squre(Object x) 
    { 
        x._internalvalue = x._internalvalue * x._internalvalue; 
        return x; 
    } 
    
    x = squre(x); 
    

    ここで起こるプロセスは完全に異なっている:=記号はない自動的は、オブジェクトに適用されないので、あなたはrule of threeと呼ばれるものを実装する必要があります、あなたします代入演算子が見つかります。ただし、代入演算子は、メモリ内に新しい(一時的な)オブジェクトを再作成し、代入演算子を呼び出してから、このオブジェクトのメモリをオリジナルのxにコピーする必要があるため、非常に高価です。

    また、オブジェクトを関数の引数として渡すと、プロセッサはこのオブジェクトが取ったメモリ全体をスタックにコピーして、関数内でそのオブジェクトにアクセスすることが非常にコスト高になります。

    質問に答えるために、単純な古い整数よりも大きい構造やオブジェクトを操作し始めたときに、参照とポインタを使用することの利点が分かり始めます。

    リファレンスを使用してプログラミングすると、パフォーマンスが向上し、大きなオブジェクトを操作するときにスタックオーバーフローのリスクが制限されます。

    +0

    OKしかし、C#では何が起きているのですか?あなたはrefとoutまたはsを知っていますこのような何かが、私はどこかで使用中にそれを見たことを覚えていない。あるいは、私は見ただけで忘れてしまったかもしれません。 – UnTraDe

    0

    参照は、別の名前を使用して変数を参照する場合に使用します。彼らはまったく同じタイプ、値などを持っています。
    ポインタは若干異なりますが、アドレスを格納する新しいタイプです。

    int i; 
    Int &ref = i; 
    Int *pointer = &i; 
    

    次に、refと* pointerは実際は同じものですが、iの値です。
    しかし、リテラル "ref"はちょうど "i"(初期化後は決して変更できない)ですが、 "ポインタ"は一時的にiを指していることを知る必要があります。
    ほとんどの場合、彼らは同じことです。
    次に、いつ参照またはポインタを使用しますか?
    私の意見では、より便利な使い方です。
    たとえば、参照を変更することはできませんが、ポインタは異なるものを指しています。^ _^
    ああ、私はコピーのコストを忘れて、他の答えを確認してください。

    +0

    答えをありがとう! – UnTraDe

    関連する問題