これらは同じですか:
int foo(bar* p) {
return p->someInt();
}
と
int foo(bar& r) {
return r.someInt();
}
ヌルポインタの可能性を無視します。これらの2つの関数someInt()
は、仮想であるか、bar
またはのサブクラスが渡されるかどうかに関係なく、機能的に同一bar
ですか?
これは何かをスライスしますか:
bar& ref = *ptr_to_bar;
これらは同じですか:
int foo(bar* p) {
return p->someInt();
}
と
int foo(bar& r) {
return r.someInt();
}
ヌルポインタの可能性を無視します。これらの2つの関数someInt()
は、仮想であるか、bar
またはのサブクラスが渡されるかどうかに関係なく、機能的に同一bar
ですか?
これは何かをスライスしますか:
bar& ref = *ptr_to_bar;
C++ 参照は、ポインターを使用して実装されるように標準で意図的に指定されていません。参照は、変数へのポインターというよりも、変数の「同義語」に似ています。このセマンティクスは、状況によってはポインターがやり過ぎになることがわかっている場合に、コンパイラーの最適化の可能性を開きます。
さらにいくつかの違い:
すべてのシンタックスシュガーと、一方では実行でき、他方では実行できない可能性と、他の回答で説明されているポインターと参照の違いを無視します(他の質問への)...ええ、これら2つは機能的にまったく同じです!どちらも関数を呼び出し、仮想関数を同等に適切に処理します。
いいえ、あなたのラインはスライスしません。ポインターが指すオブジェクトに参照を直接バインドするだけです。
どちらか一方を使用する理由についてのいくつかの質問:
自分で違いを見つけようとする代わりに、知りたい場合に備えてそれらに委任します.
参照は定数ポインタです。つまり、参照を変更して他のオブジェクトを参照することはできません。変更すると、参照オブジェクトの値が変更されます。
例:
int j = 10;
int &i = j;
int l = 20;
i = l; // Now value of j = 20
int *k = &j;
k = &l; // Value of j is still 10
はい、機能的には同じです。参照は、使用する前にオブジェクトに設定する必要があるため、null ポインターや無効なメモリへのポインターを処理する必要はありません。
意味上の違いを確認することも重要です。
私は長い間 C++ を使っていないので、あなたの質問に答えるつもりはありません (申し訳ありません)。しかし、Eric Lippertがポインタ/参照に関する優れた記事を投稿したところです。
スライスについて下部に隠された 2 番目の質問に誰かが答えたかどうかはわかりません... いいえ、スライスは発生しません。
スライスとは、派生オブジェクトが基本クラス オブジェクトに割り当てられる (コピーされる) ことです。つまり、派生クラスの特殊化が "スライス" されます。オブジェクトがコピーされると言ったことに注意してください。コピー/代入されるポインタについて話しているのではなく、オブジェクト自体について話しているのです。
あなたの例では、それは起こっていません。参照の初期化で右辺値として使用されている Bar オブジェクトへのポインターを逆参照しているだけです (その結果、Bar オブジェクトが生成されます)。専門用語が正しいかどうかわかりません...
関数は明らかに「同じ」ではありませんが、仮想動作に関しては同様に動作します。スライスに関しては、参照やポインターではなく、値を扱う場合にのみ発生します。