2013-11-03 1 views
5

私はそれを読んでいます:関数呼び出しパラメータは常に新しいオブジェクトですか?

Javaでは、すべてのパラメータが値渡されます。私は、関数へのポインタを渡すと、その関数に私はポインタを変更する場合は、これは、その識別子を使用したオブジェクトを変更しないであろう

value, 
reference, or 
const-reference 

:C++では、パラメータは によって渡すことができますそれをパラメータとして指定するには、関数に渡されたポインタのみを変更します。

実際は、技術的には、C++ではすべてがVALUEでCOPYされますが、このコピーされた値はメモリアドレス(ポインタまたは参照)として使用できるという点で違います。したがって、既存のポインタ関数のパラメータとして渡されなければなりません。そのポインタによって保持されているメモリアドレスの値ではなく、そのメモリアドレスの値を渡す必要があります。

したがって、すべての関数パラメータは、特定の単一の呼び出しでパラメータとして機能するように特別に作成された既存のオブジェクトから派生した新しいコピーであり、実際の既存のオブジェクトには正しいものはありませんか?

実際C++すべてがコピーされた値によって渡されるで技術的に、差はこのコピーされた値がメモリアドレス(ポインタまたは参照)として使用することができることであることを意味する
+0

はい、これは技術的にあります本当。意味的には、参照を渡すこと( 'int&'のように)は異なっていると考えることができます。しかし、CPU上で実行される実際のコードはまだ変更できないメモリアドレスを押しています。 –

+0

参照渡しは、ポインタを値渡しすることとは意味的に大きく異なります。値でポインタを渡すには、ポインタを渡すために何かのアドレスを明示的に取る必要があります。関数内では、指示されたものに対して操作を実行するために逆参照する必要があります。参照渡しでは、これらのことのいずれも行いません。値渡しのように何かを渡し、値を操作しているかのようにパラメータで操作する関数内で渡します。これら2つを混乱させないでください。 – newacct

答えて

4

Javaでは、すべてのパラメータが値渡しされます。

オブジェクト参照が値渡しされ、オブジェクトが突然変異をサポートしている場合、呼び出し元は渡されたオブジェクトを変更して、参照渡しのように見えるため、やや誤解を招きます。実際にC++すべてがコピーされた値によって渡されるで技術的に、差はこのコピーされた値がメモリアドレス(ポインタまたは参照)として使用することができるということであるので、私は変更したい場合を意味

関数パラメータとして渡される既存のポインタは、そのポインタが保持するメモリアドレスの値ではなく、そのメモリアドレスの値を渡す必要があります。

この評価は正しいです。ポインタ渡しと参照渡しすることは、まだ少なくとも論理的に、呼び出される関数の空間で何かのコピーを作成します。

オブジェクトは値渡しされる
  • 、自身が
  • に作成されたオブジェクトのコピーオブジェクトは参照によって渡された場合、オブジェクトがポインタにより渡されると
  • 、ポインタのコピーが
  • 作成され、参照のコピーが呼び出し元に渡されるどんな、要するに

に作成され、値渡しされます。場合によっては、渡された値を使用して元のオブジェクトを変更することができます。

最適化とインライン化を検討すると、処理が複雑になります。ポインタや参照のコピーは作成されませんが、全体的なロジックは同じままです。

+0

"効果的に見せるようにしました。" NO。大きな違いがあります。 – newacct

+0

@newacctマインドはより具体的ですか?どのような意味で私はかなり具体的だったと思うので、それはrefによってパスのように見えるので、 "ノー"とはまったく正義をしていないと鈍く言っていますか? – dasblinkenlight

+0

値渡しと渡し渡しは、渡される変数を扱う非常に具体的な意味的意味を持ちます。ポインタであれば、変数が指すオブジェクトとは何の関係もありません。 Javaには値渡し(pass-by-value)しかありません。この違いを泥だらけにしようとするのは、これについて多くの人が混乱している理由です。 – newacct

1

はいほとんどすべての一般的なプログラミング言語に対して、技術的に正しいと仮定しています。どうして? は参照渡しであることに注意してください。は、ソフトウェア抽象度です。 CPUが実際に何をするのですか(もちろん、これは関数呼び出し規則に依存しますが、私は単純化しています)は、データをレジスタにコピーすることです。

同じ値で作業していることをシミュレートするには、元のデータのメモリアドレス、つまりポインタを渡すことが最も一般的な言語です。 Cは何を参照することでシミュレーションするのですか、C++が行うこと(参考文献は実際にはポインタです)、それでJavaがすることです。

0

関数に渡されるものは、実際には一意のオブジェクトです。しかし、我々はobject Xを持っている場合、私たちは、参照object& Y = X;を作る取り、その後、object& Z = X;、その後、私たちは三つの「オブジェクト」を持っている - Xタイプobject、およびYobjectへの型参照であるZです。 object - YZという1つの "実際の"インスタンスだけが同じXを参照しています。

同様に、我々は、関数への参照渡した場合:

void func(object& R) 
{ 
    ... 
} 

func(X); 

機能がXへの参照であるオブジェクト受け取ることになりますと - 関数があるかのように見えますそれは実際にはXを修正しています。それは参照の仕組みであり、参照の実際の値は元のオブジェクトを参照するものです。

私が言うことは、「関数に渡されるものはすべて一意のオブジェクトですが、参照の場合は同じ元のオブジェクトを参照している可能性があります」ということです。

C++のポインタと参照は、2つの点以外は非常によく似ています。 1.参照は特定のオブジェクトに対して一度しか初期化できません。また、参照は実際にはオブジェクトは、「何もない」または「まだ設定されていません」という参照を持つことはできません。ただし、元々参照されていたオブジェクトが存在しなくなった「古い」参照があります。 2.参照は、基本オブジェクトと同じ構文を使用します。 r.member = 42;、ここでポインタはオブジェクトの内容に「得る」ために*pまたはp->member = 42;を使用します。

[はい、それはポインタと参照が「内部で同じものではありません」あるコンパイラを定義するためにC++仕様の範囲内で、完全に可能だが、これまでのところ私は1つを見たことがない]