矢印演算子 `->`の代わりに何を使用できますか?


112

矢印演算子(->)の同義語は何ですか?

回答:


148

次の2つの式は同等です。

a->b

(*a).b

(Konradが言及するように、オペレーターのオーバーロードが必要ですが、それは異常です)。


9
オーバーロードの問題は、あなたが考えるよりもはるかに珍しいことではありません。少し前まで、STLインプリメンターには->、一部のイテレータータイプのオーバーロードされた演算子がなかったため、を使用する必要がありました*.。多くの図書館はそれらを矛盾して定義しています。テンプレートを使用していて、正確なタイプがわからない場合は、本当に煩わしくなります。
Konrad Rudolph、

1
a[0].b代わりに行うこともできます(*a).b。しかし、それは適切に構造化されていません。
Sellorio 2013年

2
何年にもわたるc#プログラミングの後、c ++に戻ることは、認知的に負担がかかるだけでなく、c ++構文は醜く、不快です。使用後はシャワーを浴びたい気がします。CおよびC ++で書かれたプログラムは、悪いプログラミングを奨励するだけです。Appleはpre-unixで、言語をPascalと同じくらいかわいくするのに苦労していました。
ATL_DEV 2018

@ATL_DEV醜いものの多くはもう慣用的なものとは見なされていないと私は主張しますが、残念ながら、それはあなたが実践的なC ++プログラマーとしての知識がないことを許容できるわけではありません。また、構文的に適切なパスは、多くの場合、意味的に適切なパスではありませんが、悪化することなく改善されています。しかし、再びC ++ストックホルム症候群があります。
Tim Seguine、2018

@TimSeguineきれいなコードを見たい場合は、Macintosh内部のドキュメントを参照してください。彼らはキャメルケースを発明したと思います。非常にわかりやすい変数名とエレガントな形式のコード。彼らは、後のCコードを以前のPascalコードとほとんど同じくらい豪華にした。
ATL_DEV 2018

70

a->b通常、の同義語です(*a).b。ここで括弧のは理由オペレーターの結合強度が必要です*.*a.bので、動作しないでしょう.バインドが強く、最初に実行されます。したがって、これはと同等*(a.b)です。

けれども、過負荷に用心:両方以来->*過負荷にすることができ、その意味は大幅に異なる場合があります。


1
することでbinding strength、あなたは演算子の優先順位を意味ですか?そうでない場合、2つの違いは何ですか?
vishnuprasanth 2018年

1
@Vizkrigはい、2つの用語は同じ意味で使用されます(ただし、「演算子の優先順位」は、少なくとも近年はずっと頻繁に使用されているようです)。
Konrad Rudolph

45

C ++言語では、矢印演算子(->)をポインターの逆参照の同義語として定義し、.そのアドレスに対して-operatorを使用しています。

例えば:

オブジェクトanObject、、およびポインタがある場合aPointer

SomeClass anObject = new SomeClass();
SomeClass *aPointer = &anObject;

オブジェクトメソッドの1つを使用できるようにするには、ポインタを逆参照して、そのアドレスに対してメソッド呼び出しを実行します。

(*aPointer).method();

これは矢印演算子で書くことができます:

aPointer->method();

矢印演算子が存在する主な理由は、非常に一般的なタスクの入力を短縮し、ポインタの逆参照の前後の括弧を忘れてしまうこともあるからです。括弧を忘れた場合、.- operatorは* -operatorよりも強くバインドし、この例を次のように実行します。

*(aPointer.method()); // Not our intention!

他の回答のいくつかは、C ++演算子がオーバーロードになる可能性があること、およびそれほど一般的ではないことの両方についても言及しています。


8
new SomeClass()オブジェクトSomeClass *ではなくポインタ()を返しSomeClassます。そして、宣言anObjectから始めaPointerますが、p後で使用します。
musiphil 2012

全体的に、この説明は理論的に非常に適切です。オブジェクトの変更のみが少し複雑になります。しかし、プロセスはよりよく説明されています
Code Man

17

C ++ 0xでは、演算子は、関数またはラムダ式の戻りの型を示す2番目の意味を取得します

auto f() -> int; // "->" means "returns ..."

1
技術的には、もはや「オペレーター」ではないと思いますか、それともそうですか?
Martin Ba

6
@Martinほとんどの人は、値の計算に直接使用されない多くのものに「演算子」という単語を使用します。「::」(「スコープ演算子」)のように。これについて、規格の見方が正確にはわかりません。抽象的には、「->」は、「->」とも書かれるhaskell演算子のように、型(パラメータ)のシーケンスを戻り値の型にマッピングする関数演算子と見なすことができます。
Johannes Schaub-litb

6
私は降伏します!:-P
Martin Ba

2
JohannesSchaub - litb @:::のように、実際のオペレータである.->、標準で「スコープ解決演算子」と呼ばれています。
musiphil

13

私は主にそれを右から左に読んで「中」と呼ぶ

foo->bar->baz = qux->croak

になる:

「フーのバーのバズはクックスの鳴き声になる。」


1

-> ポインタを持っているデータにアクセスするときに使用されます。

たとえば、次のように、int intVar型の変数へのポインターptrを作成できます。

int* prt = &intVar;

次に、そのポインターの逆参照だけで、fooなどの関数を使用できます-その変数のメモリ位置の数値ではなく、ポインターが指す変数で関数を呼び出します。

(*ptr).foo();

ここに括弧がないと、コンパイラはこれを次のように理解します。 *(ptr.foo())、演算子の優先順位が望ましいものではないため、ます。

これは実際にはタイピングと同じです

ptr->foo();

その->ポインタを逆参照するため、関数を呼び出しますfoo()と、ポインターが指している変数がれます。

同様に、->クラスのメンバーにアクセスまたは設定するために使用できます。

myClass* ptr = &myClassMember;
ptr->myClassVar = 2; 

0

->を使用して関数を定義できます。

auto fun() -> int
{
return 100;
}

ラムダではありません。それは本当に機能です。「->」は、関数の戻り値の型を示します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.