Problemas de sobrecarga são muito menos incomuns do que você pensa. Não muito tempo atrás, os implementadores de STL não tinham ->operador sobrecarregado para alguns tipos de iterador, então você tinha que usar *.. Muitas bibliotecas os definem de forma inconsistente. Fica muito chato quando você trabalha com modelos e não sabe o tipo preciso.
Konrad Rudolph,
1
você também pode fazer em a[0].bvez de (*a).b. Mas não seria tão bem estruturado.
Sellorio
2
Rapaz, depois de muitos anos de programação em c #, voltar para c ++ não é apenas cognitivamente desgastante, a sintaxe de c ++ é simplesmente feia e nojenta. Tenho vontade de tomar banho depois de usar. Programas escritos em c e c ++ apenas encorajam a má programação. A Apple, pré-unix, lutou para tornar a linguagem tão bonita quanto Pascal.
ATL_DEV
@ATL_DEV Eu diria que muitas das coisas feias não são mais consideradas idiomáticas, mas infelizmente isso não significa que você pode se dar ao luxo de não estar familiarizado com elas como um programador C ++ praticante. Além disso, o caminho sintaticamente bom geralmente não é o caminho semanticamente bom, mas isso também está melhorando, não piorando. Mas, novamente, tenho a Síndrome de Estocolmo C ++.
Tim Seguine
@TimSeguine Se você quiser ver um código bonito, consulte a documentação do Macintosh. Acho que inventaram o CamelCase. Nomes de variáveis muito descritivos e código formatado com elegância. Eles conseguiram tornar seu código C posterior quase tão lindo quanto o código Pascal anterior.
ATL_DEV
70
a->bgeralmente é um sinônimo de (*a).b. Os parênteses aqui são necessários por causa da força de ligação dos operadores *e .: *a.bnão funcionaria porque .se liga mais forte e é executado primeiro. Isso é, portanto, equivalente a *(a.b).
No entanto, cuidado com a sobrecarga: como ->e *pode ser sobrecarregado, seu significado pode diferir drasticamente.
Por binding strengthque você quer dizer a precedência de operador? se não, qual é a diferença entre os dois?
vishnuprasanth
1
@Vizkrig Sim, os dois termos são usados alternadamente (embora “precedência de operador” pareça ser muito mais frequente, pelo menos nos últimos anos).
Konrad Rudolph,
45
A linguagem C ++ - define o operador de seta ( ->) como um sinônimo para desreferenciar um ponteiro e, em seguida, usa o .operador de seta nesse endereço.
Por exemplo:
Se você tem um objeto, anObjecte um ponteiro, aPointer:
Para poder usar um dos métodos de objetos, desreferencie o ponteiro e faça uma chamada de método nesse endereço:
(*aPointer).method();
Que pode ser escrito com o operador de seta:
aPointer->method();
A principal razão da existência do operador de seta é que ele encurta a digitação de uma tarefa muito comum e também meio que fácil esquecer os parênteses em torno da desreferenciação do ponteiro. Se você esquecer os parênteses, o operador.-Se vinculará com mais força do que o operador * e fará com que nosso exemplo seja executado como:
*(aPointer.method());// Not our intention!
Algumas das outras respostas também mencionaram que os operadores C ++ podem ser sobrecarregados e que isso não é tão comum.
Especificar tecnicamente que não é mais um "operador" aí, ou é?
Martin Ba
6
@Martin a maioria das pessoas usa a palavra "operador" para muitas coisas que não são usadas diretamente para calcular valores. Como para "::" ("operador de escopo"). Não sei qual é o ponto de vista da norma sobre isso, exatamente. Em um sentido abstrato, pode-se ver "->" como um operador funcional que mapeia uma seqüência de tipos (parâmetros) para um tipo de retorno, como o operador haskell, que também é escrito "->".
Johannes Schaub - litb
6
Eu me rendo! :-P
Martin Ba
2
@ JohannesSchaub-litb: ::é na verdade um operador, como .ou ->, e é chamado de "operador de resolução de escopo" no padrão.
musiphil
13
Eu leio principalmente da direita para a esquerda e chamo "em"
-> é usado para acessar dados para os quais você tem um ponteiro.
Por exemplo, você pode criar um ponteiro ptr para a variável do tipo int intVar como este:
int* prt =&intVar;
Você poderia então usar uma função, como foo, nela apenas desreferenciando esse ponteiro - para chamar a função na variável para a qual o ponteiro aponta, ao invés do valor numérico da localização da memória dessa variável:
(*ptr).foo();
Sem os parênteses aqui, o compilador entenderia isso como *(ptr.foo())devido à precedência do operador que não é o que queremos.
Na verdade, isso é o mesmo que digitar
ptr->foo();
Como o ->desreferencia esse ponteiro, chama a função foo()na variável para a qual o ponteiro está apontando para nós.
Da mesma forma, podemos usar ->para acessar ou definir um membro de uma classe:
->
operador sobrecarregado para alguns tipos de iterador, então você tinha que usar*.
. Muitas bibliotecas os definem de forma inconsistente. Fica muito chato quando você trabalha com modelos e não sabe o tipo preciso.a[0].b
vez de(*a).b
. Mas não seria tão bem estruturado.a->b
geralmente é um sinônimo de(*a).b
. Os parênteses aqui são necessários por causa da força de ligação dos operadores*
e.
:*a.b
não funcionaria porque.
se liga mais forte e é executado primeiro. Isso é, portanto, equivalente a*(a.b)
.No entanto, cuidado com a sobrecarga: como
->
e*
pode ser sobrecarregado, seu significado pode diferir drasticamente.fonte
binding strength
que você quer dizer a precedência de operador? se não, qual é a diferença entre os dois?A linguagem C ++ - define o operador de seta (
->
) como um sinônimo para desreferenciar um ponteiro e, em seguida, usa o.
operador de seta nesse endereço.Por exemplo:
Se você tem um objeto,
anObject
e um ponteiro,aPointer
:Para poder usar um dos métodos de objetos, desreferencie o ponteiro e faça uma chamada de método nesse endereço:
Que pode ser escrito com o operador de seta:
A principal razão da existência do operador de seta é que ele encurta a digitação de uma tarefa muito comum e também meio que fácil esquecer os parênteses em torno da desreferenciação do ponteiro. Se você esquecer os parênteses, o operador.-Se vinculará com mais força do que o operador * e fará com que nosso exemplo seja executado como:
Algumas das outras respostas também mencionaram que os operadores C ++ podem ser sobrecarregados e que isso não é tão comum.
fonte
new SomeClass()
retorna um ponteiro (SomeClass *
), não oSomeClass
objeto. E você começa declarandoanObject
e,aPointer
mas está usandop
depois.Em C ++ 0x, o operador obtém um segundo significado, indicando o tipo de retorno de uma função ou expressão lambda
fonte
::
é na verdade um operador, como.
ou->
, e é chamado de "operador de resolução de escopo" no padrão.Eu leio principalmente da direita para a esquerda e chamo "em"
torna-se:
"baz em bar em foo torna-se coak em qux."
fonte
->
é usado para acessar dados para os quais você tem um ponteiro.Por exemplo, você pode criar um ponteiro ptr para a variável do tipo int intVar como este:
Você poderia então usar uma função, como foo, nela apenas desreferenciando esse ponteiro - para chamar a função na variável para a qual o ponteiro aponta, ao invés do valor numérico da localização da memória dessa variável:
Sem os parênteses aqui, o compilador entenderia isso como
*(ptr.foo())
devido à precedência do operador que não é o que queremos.Na verdade, isso é o mesmo que digitar
Como o
->
desreferencia esse ponteiro, chama a funçãofoo()
na variável para a qual o ponteiro está apontando para nós.Da mesma forma, podemos usar
->
para acessar ou definir um membro de uma classe:fonte
Você pode usar -> para definir uma função.
Não é um lambda. É realmente uma função. "->" indica o tipo de retorno da função.
fonte