2010-12-14 15 views

答えて

22

この場合、ポインタの値がコピーされます(ただし、オプティマイザが最適化する可能性はありますが、必ずしもそうではありません)。この場合

int val = *pPtr; 

しかし何のコピーは行われません。

int& rVal = *pPtr; 

参照がマシン・コード・レベルの構成要素ではないので、何のコピーが行われない理由はあります。それはより高いレベルの構造体なので、コンパイラが特定のコードを生成するのではなく、内部的に使用するものです。

明らかに、関数パラメータについても同じことが言えます。

+4

最初のケースでコピーされたポインタではありません。それが指す値はコピーされた値です。 2番目のケースでは、ポインタは(論理的に)コピーされ、値はコピーされません。 –

+0

@ Sergey:良い点が非常に悪いと言われました:) – Goz

+2

私は自分自身の答えを検証するための簡単なテストプログラムを書いています。うまくいけば、これはいくつか役に立っています http://codepad.org/XDqahndf – RishiD

3

うまくいけば、呼び出された関数がその引数を値で取るとしたらどうでしょうか?

はさらに、それが参照の期待される動作です:

void inc(int &i) { ++i; } 

int main() 
{ 
    int i = 0; 
    int *j = &i; 
    inc(*j); 
    std::cout << i << std::endl; 
} 

incは、参照によりその引数を取るため、このコードは1を印刷することが期待されます。 incコールでコピーが作成された場合、コードは0と表示されます。

3

いいえ、参照は多かれ少なかれ、異なる表記法とnull参照がないという制限を持つポインタと似ています。しかし、ポインタのように、オブジェクトのアドレスだけを含んでいます。

+2

"しかし、ポインタのようにオブジェクトのアドレスだけを含んでいます。"参照には独自の存在がありません。これは、初期化されたオブジェクトのエイリアスです。だから、 "それは"アドレスが間違っているが含まれています。参照は元のオブジェクトと同じアドレスを指しているだけで、そのアドレスは含まれていません。 –

+0

どうしてですか?それはどこの場所を指し示し、アドレスを含まないのでしょうか?それはそれを含んでいます、アクセスするたびに自動的に逆参照されるため、あなたが含むアドレスにアクセスすることはできません。 –

+0

@Sergey Tachenov:コンパイラは、それがエイリアスであると仮定し、それを引き受けることができるフィクションを作成しなければなりません。これは、使用に応じて、コンパイラは* internal *ポインタを作成し、使用時に自動的に参照解除することも、場合によっては元のオブジェクトを参照することもできることを意味します。ほとんどの場合、ポインタに頼らざるを得ませんが、一日の終わりには、抽象的な考え方をするほうがよいでしょう。参照は実装方法に関係なく*エイリアス*です。 –

6

単純な場合、いいえ。より複雑な例は、しかし、があります。間接参照ポインタ(int)のタイプは、関数のパラメータ(float)の基本型と一致しないため、ここで

void foo(float const& arg); 
int * p = new int(7); 
foo(*p); 

は、一時的なオブジェクトが作成されます。変換シーケンスが存在し、変換された一時的なものはconst参照であるので、 argにバインドすることができます。