Ok operatörü `->` yerine ne kullanabilirim?


112

Ok operatörünün ( ->) eşanlamlısı nedir?

Yanıtlar:


148

Aşağıdaki iki ifade eşdeğerdir:

a->b

(*a).b

(Konrad'ın bahsettiği gibi, operatörün aşırı yüklenmesine bağlıdır, ancak bu alışılmadık bir durumdur)


9
Aşırı yükleme sorunları düşündüğünüzden çok daha az sıra dışıdır. Kısa bir süre önce, STL uygulayıcılarının ->bazı yineleyici türleri için aşırı yüklenmiş operatörü yoktu , bu yüzden kullanmanız gerekiyordu *.. Birçok kütüphane bunları tutarsız olarak tanımlar. Şablonlarla çalışırken ve kesin türü bilmediğinizde gerçekten can sıkıcı hale geliyor.
Konrad Rudolph

1
a[0].byerine de yapabilirsiniz (*a).b. Ama o kadar düzgün yapılandırılmamış.
Sellorio

2
Oğlum, yıllarca süren c # programlamasından sonra, c ++ 'ya geri dönmek sadece bilişsel olarak vergi vermekle kalmıyor, c ++ sözdizimi sadece çirkin ve berbat. Kullandıktan sonra duş almak gibi hissediyorum. C ve c ++ ile yazılmış programlar kötü programlamayı teşvik eder. Apple, unix öncesi, dili Pascal kadar güzel yapmak için mücadele etti.
ATL_DEV

@ATL_DEV Pek çok çirkin şeyin artık deyimsel olarak kabul edilmediğini iddia ediyorum, ancak ne yazık ki bu, pratik bir C ++ programcısı olarak ona aşina olamayacağınız anlamına gelmez. Ayrıca sözdizimsel olarak güzel yol, çoğu zaman anlamsal olarak güzel bir yol değildir, ama aynı zamanda daha da kötü değil, daha da iyiye gitmektedir. Ama yine de C ++ Stockholm Sendromu var.
Tim Seguine

@TimSeguine Eğer güzel bir kod görmek isterseniz, Macintosh'un içindeki belgelere bakın. Sanırım CamelCase'i icat ettiler. Çok açıklayıcı değişken adları ve zarif bir şekilde biçimlendirilmiş kod. Sonraki C kodlarını neredeyse önceki Pascal kodları kadar muhteşem yapmayı başardılar.
ATL_DEV

70

a->bgenellikle eşanlamlıdır (*a).b. Buradaki parantezler, operatörlerin bağlanma gücü nedeniyle gereklidir *ve .: *a.bçalışmaz çünkü .daha güçlü bağlanır ve ilk olarak çalıştırılır. Bu, dolayısıyla eşdeğerdir *(a.b).

Yine de aşırı yüklemeye dikkat edin: Hem ->ve hem *de aşırı yüklenebildiğinden, anlamları büyük ölçüde farklılık gösterebilir.


1
By binding strengthEğer operatör öncelik demek? değilse ikisi arasındaki fark nedir?
vishnuprasanth

1
@Vizkrig Evet, iki terim birbirinin yerine kullanılıyor (her ne kadar “operatör önceliği” en azından son yıllarda çok daha sık görünüyor).
Konrad Rudolph

45

C ++ dili, ok operatörünü ( ->) bir işaretçinin .başvurusunu kaldırmanın eşanlamlısı olarak tanımlar ve sonra bu adreste -operatörü kullanır .

Örneğin:

Bir nesneniz anObjectve işaretçiniz varsa aPointer:

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

İşaretçiye başvurduğunuz nesne yöntemlerinden birini kullanabilmek ve bu adreste bir yöntem çağrısı yapmak için:

(*aPointer).method();

Ok operatörü ile yazılabilir:

aPointer->method();

Ok operatörünün var olmasının temel nedeni, çok yaygın bir görevin yazımını kısaltması ve aynı zamanda işaretçinin referansını kaldırmanın etrafındaki parantezleri unutmanın bir nevi kolay olmasıdır. Parantezleri unuttuysanız,.-Operatörü * -operator'dan daha güçlü bağlanır ve örneğimizin şu şekilde yürütülmesini sağlar:

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

Diğer yanıtlardan bazıları, hem C ++ operatörlerinin aşırı yüklenebileceğinden hem de bu kadar yaygın olmadığından bahsetmiştir.


8
new SomeClass()nesne SomeClass *değil bir işaretçi ( ) döndürür SomeClass. Ve bildirerek ile başlar anObjectve aPointerancak kullandığınız psonradan.
musiphil

Genel olarak bu açıklama teorik olarak çok yerinde, sadece nesnelerin değişmesi onu biraz kıvrımlı hale getiriyor. Ancak süreç daha iyi açıklanıyor
Code Man

17

C ++ 0x'de, operatör, bir işlevin veya lambda ifadesinin dönüş türünü gösteren ikinci bir anlam alır.

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

1
Teknik olarak işaretlemek artık orada bir "operatör" değil, değil mi?
Martin Ba

6
@Martin, değerleri hesaplamak için doğrudan kullanılmayan birçok şey için "operatör" kelimesini kullanır. "::" ("kapsam operatörü") gibi. Bu konuda standardın bakış açısının ne olduğunu tam olarak bilmiyorum. Soyut bir anlamda, "->", "->" yazılan haskell operatörü gibi bir dönüş tipine bir dizi tip (parametre) eşleştiren işlevsel bir operatör olarak görülebilir.
Johannes Schaub -

6
Teslim oluyorum! :-P
Martin Ba

2
@ JohannesSchaub-litb: ::aslında .veya gibi bir operatördür ->ve standartta "kapsam çözümleme operatörü" olarak adlandırılır.
musiphil

13

Çoğunlukla sağdan sola okurum ve "içeri" diyorum

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

dönüşür:

"foo'daki baz in bar qux'te vıraklıyor."


1

-> bir işaretçinizin olduğu verilere erişirken kullanılır.

Örneğin, intVar türünde bir değişkene ptr işaretçisi şu şekilde oluşturabilirsiniz:

int* prt = &intVar;

Daha sonra foo gibi bir işlevi, yalnızca o işaretçiyi referans alarak kaldırarak kullanabilirsiniz - işlevi, o değişkenin bellek konumunun sayısal değeri yerine işaretçinin işaret ettiği değişken üzerinde çağırmak için:

(*ptr).foo();

Buradaki parantezler olmadan, derleyici bunu şu şekilde anlayacaktır: *(ptr.foo()) istediğimiz şey olmayan operatör önceliğine bağlı .

Bu aslında yazmakla aynı

ptr->foo();

Şöyle ->dereferences işaretçi ve böylece işlevini çağırırfoo() işaretçi bizim için işaret ettiği değişkeni.

Benzer şekilde, ->bir sınıfın üyesine erişmek veya ayarlamak için kullanabiliriz :

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

0

Bir işlevi tanımlamak için -> kullanabilirsiniz.

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

Lambda değil. Bu gerçekten bir işlev. "->", işlevin dönüş türünü gösterir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.