Відповіді:
Наступні два вирази еквівалентні:
a->b
(*a).b
(за умови перевантаження оператора, як згадує Конрад, але це незвично).
a[0].b
замість цього (*a).b
. Але це було б не так правильно.
a->b
взагалі є синонімом для (*a).b
. Дужки тут потрібні через силу зв'язування операторів *
і .
: *a.b
не працюватимуть, тому що .
зв'язується сильніше і виконується першим. Таким чином, це рівнозначно *(a.b)
.
Остерігайтеся перевантаження, хоча: Так як ->
і *
можуть бути перевантажені, їх зміст може істотно відрізнятися.
binding strength
ви маєте в виду оператор пріоритет? якщо ні, то яка різниця між ними?
Мова C ++ визначає оператор стрілки ( ->
) як синонім перенаправлення покажчика, а потім використовує .
-operator за цією адресою.
Наприклад:
Якщо у вас є об'єкт anObject
і вказівник, aPointer
виконайте вказані нижче дії :
SomeClass anObject = new SomeClass();
SomeClass *aPointer = &anObject;
Щоб мати можливість використовувати один з методів об'єктів, ви відмежуєте покажчик і виконайте виклик методу за цією адресою:
(*aPointer).method();
Що можна записати за допомогою оператора стрілки:
aPointer->method();
Основна причина існування оператора стрілки полягає в тому, що це скорочує введення дуже поширеного завдання, а також легко забути дужки навколо перенаправлення вказівника. Якщо ви забули круглі дужки,. -Оператор прив’яже сильніше, ніж * -operator, і зробить наш приклад виконаним як:
*(aPointer.method()); // Not our intention!
Деякі інші відповіді також згадують про те, що оператори C ++ можуть бути перевантажені і що це не так часто.
new SomeClass()
повертає вказівник ( SomeClass *
), а не SomeClass
об’єкт. І ви починаєте з декларуванням anObject
і , aPointer
але ви використовуєте p
згодом.
У C ++ 0x оператор отримує друге значення, що вказує на тип повернення функції або лямбда-вираз
auto f() -> int; // "->" means "returns ..."
::
насправді оператор, як-от .
або ->
, і називається в стандарті "оператором роздільної здатності".
->
використовується для доступу до даних, на які ви маєте вказівник.
Наприклад, ви можете створити вказівник ptr на змінну типу int intVar, як це:
int* prt = &intVar;
Тоді ви можете використовувати функцію, таку як foo, на ній лише шляхом перенаправлення цього вказівника - для виклику функції на змінній, на яку вказує вказівник, а не на числове значення місця пам'яті цієї змінної:
(*ptr).foo();
Без дужок тут компілятор зрозумів би це як *(ptr.foo())
перевагу оператора, яке не є тим, що ми хочемо.
Це насправді так само, як і друкувати
ptr->foo();
Як ->
відміни, що foo()
вказують , і так називає функцію змінної, на яку вказує нам вказівник.
Так само ми можемо використовувати ->
для доступу або встановлення члена класу:
myClass* ptr = &myClassMember;
ptr->myClassVar = 2;
->
оператора для деяких типів ітераторів, тому вам довелося користуватися*.
. Багато бібліотек визначають їх непослідовно. Стає по-справжньому дратує, коли ви працюєте з шаблонами і не знаєте точного типу.