286

他の C 派生言語 (Java や C# など) から C++ に移行すると、C++ にはクラスのメンバーを参照する 3 つの方法a::b( 、a.b、および) があることに最初は非常に混乱しますa->b。これらの演算子のどれをいつ使用しますか?

_(注: これは [Stack Overflow の C++ FAQ](https://stackoverflow.com/questions/tagged/c++-faq) へのエントリであることを意図しています。FAQ をこの形式で提供するという考えを批判したい場合、[このすべてを開始したメタへの投稿](https://meta.stackexchange.com/questions/68647/setting-up-a-faq-for-the-c-tag) がそれを行う場所になります. その質問への回答は [C++ チャットルーム](https://chat.stackoverflow.com/rooms/10/c-lounge) で監視されており、FAQ のアイデアが最初に始まった場所であるため、あなたの回答は非常に可能性が高いです。アイデアを思いついた人に読んでもらうために。)_
4

4 に答える 4

294

C++ がクラスまたはクラス オブジェクトのメンバーにアクセスするために使用する 3 つの異なる演算子、つまり二重コロン::、ドット.、および矢印->は、常に明確に定義された 3 つの異なるシナリオに使用されます。これを知っていれば、どのコードを見ても、、、またはをそれぞれ見るだけで、すぐにa多くのことを知ることができます。ba::ba.ba->b

  1. a::bbがクラス (または名前空間) のメンバーである場合にのみ使用されますa。つまり、この場合aは常にクラス (または名前空間) の名前になります。

  2. a.bbがオブジェクトのメンバー (またはオブジェクトへの参照) である場合にのみ使用されますa。したがって、 fora.ba常にクラスの実際のオブジェクト (またはオブジェクトへの参照) になります。

  3. a->bは、もともとは の略記です(*a).b。ただし、->オーバーロードできるメンバー アクセス演算子は のみであるため、 がオーバーaロードするクラスのオブジェクトである場合operator->(このような一般的な型はスマート ポインターとイテレーターです)、その意味はクラス デザイナーが実装したものになります。結論として、 がポインタであるa->b場合、 はポインタが参照するオブジェクトのメンバーになります。ただし、がこの演算子をオーバーロードするクラスのオブジェクトである場合、オーバーロードされた演算子関数が呼び出されます。abaaoperator->()


細字:

  • C++ では、、、またはとして宣言されたclassstructunion「クラス型」と見なされます。したがって、上記は3つすべてを指します。
  • 参照は意味的にはオブジェクトのエイリアスなので、#3 にも「またはポインタへの参照」を追加する必要がありました。T*&ただし、ポインター ( ) への参照はめったに使用されないため、これは役立つというよりも混乱を招くと思いました。
  • ドット演算子と矢印演算子は、オブジェクトのメンバーではない場合でも、オブジェクトから静的クラス メンバーを参照するために使用できます。(これを指摘してくれたOliに感謝します!)
于 2011-02-13T14:11:48.407 に答える
10

ドット演算子は、メンバーを直接選択するシナリオで使用されます。

print(a.b)

ここではb、 object の直接のメンバーである にアクセスしていますa。したがって、主にaオブジェクトでbあり、のメンバー(関数/変数など)ですa


アロー演算子は、間接メンバー選択シナリオで使用されます。

print(a->b)

ここではb、 が指すオブジェクトのメンバーであるにアクセスしていますa。これは(*a).band の省略形であり、ここでaは主にオブジェクトへのポインターでbあり、そのオブジェクトのメンバーです。


二重コロン (スコープ) 演算子は、名前空間に関連する直接メンバー選択シナリオで使用されます。

print(a::b)

ここではb、クラス/名前空間のメンバーであるにアクセスしていますa。つまり、主にaクラス/名前空間でbあり、のメンバー(関数/変数など)ですa

于 2020-01-24T06:06:44.287 に答える