参照はエイリアスとして定義されています。標準の実装方法はあまり変わらないが、標準の表現方法は明記されていない。本質的に:一般的なケースで
- 、参照は、ボンネットの下に、(ポインタのような)オブジェクトのアドレスである
- 可能な場合、コンパイラは、間接
を除去するために努める
あなたのプログラムで始まる、私たちはそれを変換する方法を見てみましょう:
int main()
{
int *pi = new int(50);
int &ri = *pi;
ri = 30;
std::cout << "val = " << ri << " , " << *pi << std::endl;
}
我々はできますそれがバインドされているオブジェクトは、コンパイラによって知られているので、ri
を排除:
int main()
{
int *pi = new int(50);
*pi = 30;
std::cout << "val = " << *pi << " , " << *pi << std::endl;
}
その最終値は、コンパイラによって知られているので、我々は*pi
を排除することができます
int main() {
new int(50); // stupid possible side effect usually forbid to optimize this out
std::cout << "val = " << 30 << " , " << 30 << std::endl;
}
私はあなたにそれを注意しますたとえば、new
呼び出しは完全に無用です。動的に割り当てられていないオブジェクトも参照できます。
int main() {
int i = 50;
int& ri = i;
ri = 30;
std::cout << "val = " << ri << " < " << i << std::endl;
}
も有効で、メモリリークはありませんでした。
バック表現の間我々の違いを取得:
void swap(Foo& left, Foo& right);
典型的に実装されている:この場合
void swap(Foo* left, Foo* right);
、参照は、(一部)を服用してしまう空間(ASポインタと同じくらい)。と一方
:
class Object {
public:
Object(): foo(f), f() {}
Foo const& foo;
void set(Foo const& value);
private:
Foo f;
};
コンパイラは、一般的にfoo
ランタイム表現を与えることはありませます。それがconst
の参照であるという事実は、f
で呼び出される可能なメソッドを変更しないメソッド(意味的な違い)に制限するために使用されますが、実行時には直接f
が渡されます。
いいえ参照はメモリを消費せず、変数や参照に加えられた変更はお互いに反映されます。それだけであなたが知る必要があります。コンパイラが処理するものはすべて、あなたは必要ありません心配して。 –
参考文献はポインタの構文が少し違うと考えるのが一番です。参照のC++仕様は、技術的にはポインタではないが、コンパイラがそれらをポインタ以外のものとして扱い、依然として効率的であるとは考えにくいものである。 _Nullの処理はわずかに異なりますが、論理的にのみ、コンパイラは何もしない可能性があります_ –