Ответы:
Следующие два выражения эквивалентны:
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;
->
оператора для некоторых типов итераторов, поэтому приходилось использовать*.
. Многие библиотеки определяют их непоследовательно. Действительно раздражает, когда вы работаете с шаблонами и не знаете точный тип.