2017-11-05 11 views
2

私はStroustrup's第4版を読んでいます:The C++ Programming Language。私はpython/javaのバックグラウンドを持っているので、最初の4つの章はこれまでのところうまくいきます。私はそれがオブジェクトではなくコピーへの参照を返していることを考え出しC++:実際には逆参照は何ですか?

まず:この質問を書く一日中試みを始めました

complex& operator+=(complex z) { re+=z.re , im+=z.im; return ∗this; } 

を:私が見たChapter 3

。これで確認できたのでquestion

そして私は対このquestion

からの定期的な変数reference variableへの参照を返すの違いを理解することができましたそして、私はなぜ疑問に私を導く私自身の裁判

class Test { 
public: 

    Test():x{5}{} 

    int x; 

    void setX(int a) {x = a;} 

    Test& operator+=(Test z) {x+=z.x; return *this;} 

    // the keyword this is a pointer 
    Test* getTest() {return this;} 

    // but I can return the reference by *this 
    Test& getTest1() {return *this;} 

    // or I can return a copy 
    Test getTest2() {return *this;} 

}; 

をしましたそれはde-referenceと呼ばれ、そう予想したように、私はこの裁判に

int x = 8; 
int* p = &x; 
int y = *p; 
int& z = *p; 

x++; // let's have some fun 

std::cout << y << std::endl; 
std::cout << z << std::endl; 

をやっているy = 8z = 9の場合、de-referenceはどのようにしてaddressを返し、もう1つのケースにvalueを返しましたか?もっと重要なことは、C++はどのように区別されていますか?

+3

リファレンスは自動的に逆参照されたポインタと考えることができますが、それはまったくアドレスではありません。 – iksemyonov

+0

@iksemyonovアドレスまたは値でない場合は、それは何ですか? –

+0

@SamHammamyアドレスは値です。 – melpomene

答えて

1

y = 8とz = 9と同様に、デリファレンスは1つのケースでアドレスを返し、もう1つのケースでは値を返しますか?もっと重要なのは、C++がその区別をどのようにしているのでしょうか?

逆参照は、両方の場合で参照された実際のものを返しました。だから、C++には違いはありません。違いは、逆参照の結果で行われたことにあります。

int j = <something>;を実行すると、その結果がjの初期化に使用されます。 jは整数なので、<something>は整数値でなければなりません。

int &j = <something>;を実行すると、何かの結果が引き続きjの初期化に使用されます。しかし今、jは整数への参照であり、<something>は整数値でなくてはなりません。

したがって、*thisはどちらの場合も同じです。値の使い方は、その値の計算方法には影響しません。しかし、それをどのように使用するかは、使用するときに何が起こるかに影響します。そして、これらの2つのコードは逆参照オブジェクトを別々に使います。ある場合には、その値が取られます。それ以外の場合は、参照がバインドされています。

+0

ありがとうDavid!これは、 'int&j = some_function'を実行できることを意味します:' return'ではなく 'functionの名前'でしょうか?それで私は 'j()'を後で行うことができますか? –

+0

@SamHammamyいいえ。関数がintへの参照ではないためです。 'j'は" intへの参照 "型であるので、' = 'の右側にあるものは、関数ではなく整数への参照でなければならない(または変換可能でなければならない)。また、整数への参照は呼び出し可能ではありません。だから 'j()'は意味をなさない。 –

3

Testクラスの関数とまったく同じです。

int y = *p; 
int& z = *p; 

ypポイントへのコピーです。 zは、pが指し示す(アドレスではない)への参照であるです。したがって、zを変更すると、*pが変更され、その逆もあります。しかし、yを変更しても*pには影響しません。

+0

ありがとう!それはそれをたくさん明確にします。しかし、もし 'z'がアドレスでなければ、正確には何ですか?はい、 'x'の'参照 'ですが、どのように表現されていますか? linuxのシンボリックリンクには、ターゲットファイルへのパスが格納されています –

+0

参照はそれぞれ独自のタイプです。参照とポインタの違いは微妙です。顕著な違いは、ポインタがNULLになり、参照ができないことです。詳細については、この記事を参照してください。 https://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in – MFisherKDX

+0

@MFisherKDX IIRC参照は*決して*決してnullになるnull値を参照するために悪用される(または少なくともC++の1つのバージョンでは可能でした)場合があります(通常は工夫していますが)。 – errantlinguist

1

ポインタint* pは、タイプintのデータが存在するアドレスを指しているとみなすことができます。これを参照解除すると、システムはそのメモリアドレスの値を取得します(アドレスはpの実際の値です)。 int y = *p;の場合は、そのint値のコピーをlocator valueyとしてスタックに入れます。

一方、*p = 13;に左側にデ参照すると、右辺値13pの値によって示されるメモリアドレスに格納されint*pを交換することを意味します。 int値のコピーはpによって指さむしろ*p(すなわちによってによって保持された実際の値を返した特定のメモリアドレスにあるものは何でも左側の基準

int& z = *p;int& z左辺値参照はありませんp自体)。

これは、あなたの考案されたケースで大きな違いはありませんが、同じインスタンスに同じ方法で二回呼び出されますFoo::incrementCount()値、

Foo* p = new Foo(); 
p->incrementCount(); 

Foo& ref = *p; 
ref.incrementCount(); 

Fooクラスを与えられました。対照的に、Foo foo = *pは実際にはFooインスタンス全体をコピーし、スタックに別のコピーを作成します。したがって、foo.incrementValue()を呼び出すと、依然としてpが指す別のオブジェクトには影響しません。

関連する問題