参照渡しを使用するC++では、引数から本質的にポインタである関数のパラメータに渡したもののアドレスを参照しますよね?
いいえ。参照は、既存の変数のエイリアス (別名) です。
しかし、アセンブリ レベルでは、実装によって、参照された変数のアドレスが、呼び出された関数が使用するアドレス レジスタ (または同様のもの) に格納される場合があります (それが意味する場合)。
しかし、簡単にするために、自動的に逆参照されるポインターと考えることができます (これは、私が最初に始めたときに行ったことです)。しかし、言語の話に入ると、参照は実際にはポインターとは根本的に異なります。
つまり、それらは本質的にエイリアスとすべて同じものですが、ポインタもメモリ空間を必要としませんか?
C++ レベルのポインターは (アドレス可能であるため) スペースを必要とします。ポインタのアドレスを取得できます。基本的に、参照にはスペースは必要ありません (アドレスを取得できないため)。実装レベルでは、コンパイラが実装する方法に応じて、物理メモリの場所がある場合とない場合があります。
したがって、パラメーター関数にあるものは何でも、B を呼び出して、渡された引数が何であれ、そのメモリ位置を指すようにすべきではありません。
上記をコード例で説明していただければよかったです。しかし、私は理解していると思います。関数がインライン化されていないと仮定すると、参照として渡されるパラメーターには、元のオブジェクトへの何らかの形式のリンクが必要です (参照は常に基本的にライブ オブジェクトを参照するため)。それで、それはどのようにしますか。コンパイラの実装の詳細 (気にする必要はありません)。しかし、おそらくスタック上のポインターか、アドレスレジスター内の単なるアドレスです。
次に、値のメモリ位置はどれですか (A が値のメモリ位置を引数として渡したため)?
多分かどうか。参照には、言語レベルでの物理的な場所はありません。したがって、コンパイラはそれを使って多くの素敵な小さなトリックを実行できます。
値渡しを使用する Java では、渡されたアドレスのコピーを作成します (たとえば、オブジェクトへの参照)。
Java では、参照を値で渡します。しかし、Java 参照は基本的に、メモリー位置へのポインターにすぎません。したがって、ポインターを値で渡しています。これは使用する1つのテクニックです。幸いなことに、C++ は 1 つの手法に限定されません。
パラメータは値または参照で渡すことができます。値または参照によってオブジェクトへのポインターを渡すこともできます。そのため、状況に応じて使用する興味深いテクニックがいくつかあります。
したがって、最終的には、値渡しと参照渡しの違いが本当にわかりません。
おそらく、Java 参照 (値によって渡される) について考えているためです。
C++ で。値渡しの場合は、パラメーターとして渡される新しいオブジェクトを作成しています (つまり、元のオブジェクトのコピーを作成するため、コストがかかる可能性があります)。参照渡しの場合は、エイリアスをオブジェクトに渡しています。したがって、オブジェクトを操作すると、元のオブジェクトが変更されます。
int inc(int val) // pass by value
{
return ++val; // increment the passed value and return as a result.
}
int incref(int& val) // pass by reference
{
return ++val; // increment the reference.
// Since the reference is an alias this increment affects the
// original object. The result is returned.
}
void code()
{
int x = 5;
int y = inc(x); // x =5 and y = 6
int a = 8;
int b = incref(a); // a = 9 and b = 9
}
値渡しは、元の渡された引数にメモリ内のスペースを割り当て、値を指すコピーと参照渡しの両方が、値のメモリ位置を引数として渡します。関数は、値を指すために使用します。
すみません、それを失いました。