Ответы:
Следующие два выражения эквивалентны:
a->b
(*a).b
(возможна перегрузка оператора, как упоминает Конрад, но это необычно).
a[0].bвместо (*a).b. Но это было бы не так правильно.
a->bобычно является синонимом (*a).b. Круглые скобки здесь необходимы из-за силы связывания операторов *и .: *a.bне будет работать, потому что .связывает сильнее и выполняется первым. Таким образом, это эквивалентно *(a.b).
Однако остерегайтесь перегрузки: поскольку оба ->и *могут быть перегружены, их значение может сильно различаться.
binding strengthвы имеете в виду оператор приоритет? если нет, в чем разница между ними?
В языке C ++ оператор стрелки ( ->) определяется как синоним разыменования указателя, а затем для .этого адреса используется оператор -оператор .
Например:
Если у вас есть объект anObject, и указатель aPointer:
SomeClass anObject = new SomeClass();
SomeClass *aPointer = &anObject;
Чтобы иметь возможность использовать один из методов объекта, вы разыменовываете указатель и вызываете метод по этому адресу:
(*aPointer).method();
Что можно было бы написать с помощью оператора стрелки:
aPointer->method();
Основная причина существования оператора стрелки заключается в том, что он сокращает типизацию очень распространенной задачи, а также позволяет легко забыть скобки вокруг разыменования указателя. Если вы забыли круглые скобки, оператор. -Оператор будет связывать сильнее, чем * -оператор, и заставит наш пример выполняться как:
*(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;
->оператора для некоторых типов итераторов, поэтому приходилось использовать*.. Многие библиотеки определяют их непоследовательно. Действительно раздражает, когда вы работаете с шаблонами и не знаете точный тип.