2009-09-15 16 views
20

私はこの線に沿って機能を書いた:data内のすべてのフィールドを記入します関数宣言で `*&`はどういう意味ですか?

myStruct *data; 
myFunc(data); 

:呼び出し元の関数で今すぐ

void myFunc(myStruct *&out) { 
    out = new myStruct; 
    out->field1 = 1; 
    out->field2 = 2; 
} 

を、私はこのような何かを書くかもしれません。宣言で '&'を省略すると、これは機能しません。 (または、むしろ関数内ではローカルでしか動作しませんが、呼び出し側では何も変更しません)

*&」は実際に何を説明することができますか?それは奇妙に見え、私はちょうどそれの多くの感覚を作ることができません。

+5

これはC++構文であり、C – qrdl

答えて

34

C++変数宣言の&シンボルは、referenceを意味します。

これは、あなたが見ているセマンティクスを説明するポインタへの参照であることがあります。呼び出された関数は呼び出しコンテキスト内のポインタを参照するため、呼び出しコンテキスト内のポインタを変更することができます。

したがって、ここでの「手術用シンボル」は*&ではありません。それだけでは意味がありません。 *はタイプmyStruct *の一部であり、「myStructへのポインタ」であり、&が参考になるので、「outmyStructへの参照です」と読みます。

オリジナルのプログラマが私の意見では、としてそれを書くことによって、助けている可能性が

:(まだ有効ではない私の個人的なスタイルが、もちろん)

void myFunc(myStruct * &out) 

かさえ:

void myFunc(myStruct* &out) 

のもちろん、スタイルについての他の多くの意見があります。 :)

+0

ではありません。 "...他のC++での名前と同じように..."はちょっとうんざりです。 (そう言えば、それはまた、運営者のアドレスになる可能性があります)。 +1 – sbi

+0

@スビー:同意して、私はそれを変えました...今はちょっと自己参照です。 – unwind

+0

今より良いと思います。 :) Adriaanの答えが受け入れられて以来、ちょっとした学業です。 – unwind

2

は、関数の引数が割り当て可能であるので、それは、一種の同等のCでポインタへのポインタへのポインタへの参照ですC++ではwikipedia

2

を参照してください。

13

CおよびC++では、&は参照によって呼び出されます。関数が変数を変更できるようにします。 この場合、変数はmyStruct型へのポインタです。この場合、関数は新しいメモリブロックを割り当て、これをポインタ 'data'に代入します。

過去には(例えば、K & R)、これはポインタ(この場合はポインタポインタまたは**)を渡すことによって行われなければなりませんでした。参照演算子は、より読みやすいコードとより強力な型チェックを可能にします。

1

MyClassの* & MyObjectに

ここMyObjectにはMyClassのポインタへの参照です。したがって、myFunction(MyClass * & MyObject)を呼び出すことは参照によって呼び出されるため、ポインタへの参照であるMyObjectを変更することができます。しかし、myFunction(MyClass * MyObject)を実行した場合、MyObjectは値で呼び出されるため変更できません。アドレスを一時変数にコピーするだけで、MyObjectがPointであるがMyObjectではなく値を変更できます。

この場合、ライターは最初に新しい値をoutに割り当てているので、参照による呼び出しが必要なのはなぜですか。

6

これはコンストラクタを再実装しているようです。

なぜ適切なコンストラクタを作成するだけではないのですか?
C++では、structはクラスと似ています(コンストラクタを持つことができます)。

struct myStruct 
{ 
    myStruct() 
     :field1(1) 
     ,field2(2) 
    {} 
}; 

myStruct* data1 = new myStruct; 

// or Preferably use a smart pointer 
std::auto_ptr<myStruct> data2(new myStruct); 

// or a normal object 
myStruct data3; 
+0

実際、私はコンストラクタを再実装していました。ヒントありがとう! – bastibe

2

C++のほとんどのデータ型と同様に、右から左に読むと意味があります。

myStruct *&out 

outmyStructオブジェクトへのポインタ(*)への参照(&)です。 outが指しているもの(この場合はnew myStruct)を変更する必要があるため、参照にする必要があります。

6

なぜそれが&*ではないのかを説明する価値があるかもしれませんが、それ以外は逆です。その理由は、宣言が再帰的に構築されて、で、そのポインタを参照するには

& out // reference to ... 
* (& out) // reference to pointer 

のように構築括弧は、それらが冗長であるため廃棄されますが、彼らはあなたがパターンを見るのを助けることがあります。 (なぜそれらが冗長であるかを知るためには、表現がどのように見えるのか想像してください。最初にアドレスが取られ、逆参照されることに気づくでしょう - それは私たちが望む順序であり、かっこは変わりません)。注文を変更した場合、

* out // pointer to ... 
& (* out) // pointer to reference 

参照先が正しくありません。そのため注文は*&で、これは「ポインタへの参照」を意味します。

3

&は、実際の変数を関数のコピーとは対照的に参照することを意味します。これは、関数内の変数に加えられた変更が元の変数に影響を与えることを意味します。これは、ポインタを渡すときに特に混乱を招く可能性があります。ポインタは、すでに他のものへの参照です。あなたの関数の署名がこのようになった場合

void myFunc(myStruct *out); 

あなたの関数は、ポインタのコピーを渡して動作させるということが起こります。つまり、ポインタは同じものを指すが、別の変数となる。ここでは、*outに行われた変更(つまり、どの点がどこにあるか)は永続的ですが、out(ポインタ自体)の変更はmyFuncの内部でのみ適用されます。このような署名で

void myFunc(myStruct *&out); 

あなたは関数が元のポインタを参照すると宣言しています。今、ポインタ変数outに加えた変更が渡された元のポインタに影響を与えます。言われていること

、ライン

out = new myStruct; 

をポインタ変数outとない*outを変更しています。outが指し示していたものはまだ生きていますが、今度はヒープ上にmyStructの新しいインスタンスが作成され、outがそれを指すように変更されました。

関連する問題