
Bingo
Entiendo la mayoría de la sobrecarga de operadores, con la excepción de los operadores de acceso a miembros. ->
, .*
, ->*
etc
En particular, ¿qué se pasa a estas funciones de operador y qué se debe devolver?
¿Cómo funciona el operador (p. ej. operator->(...)
) sabe a qué miembro se hace referencia? ¿Puede saberlo? ¿Incluso necesita saberlo?
Finalmente, ¿hay alguna consideración constante que deba tenerse en cuenta? Por ejemplo, al sobrecargar algo como operator[]
, generalmente necesitará una versión const y no const. ¿Los operadores de acceso de miembros requieren versiones constantes y no constantes?

matapatatas
->
Este es el único realmente complicado. Debe ser una función miembro no estática y no requiere argumentos. El valor devuelto se utiliza para realizar la búsqueda de miembros.
Si el valor devuelto es otro objeto de tipo de clase, no un puntero, la búsqueda de miembros subsiguiente también es manejada por un operator->
función. Esto se denomina “comportamiento de profundización”. El lenguaje encadena la operator->
llama hasta que el último devuelve un puntero.
struct client
{ int a; };
struct proxy {
client *target;
client *operator->() const
{ return target; }
};
struct proxy2 {
proxy *target;
proxy &operator->() const
{ return * target; }
};
void f() {
client x = { 3 };
proxy y = { & x };
proxy2 z = { & y };
std::cout << x.a << y->a << z->a; // print "333"
}
->*
Este solo es complicado porque no tiene nada de especial. los no sobrecargado requiere un objeto de tipo puntero a clase en el lado izquierdo y un objeto de tipo puntero a miembro en el lado derecho. Pero cuando lo sobrecargas, puedes tomar los argumentos que quieras y devolver lo que quieras. Ni siquiera tiene que ser un miembro no estático.
En otras palabras, este es solo un operador binario normal como +
, -
y /
. Ver también: ¿Son malas las sobrecargas de operador->* libres?
.*
y .
Estos no se pueden sobrecargar. Ya hay un significado incorporado cuando el lado izquierdo es del tipo de clase. Tal vez tendría un poco de sentido poder definirlos para un puntero en el lado izquierdo, pero el comité de diseño de idiomas decidió que sería más confuso que útil.
Sobrecarga ->
, ->*
, .
y .*
solo puede completar los casos en los que una expresión no estaría definida, nunca puede cambiar el significado de una expresión que sería válida sin sobrecarga.

Totonga
Operador -> es especial.
“Tiene restricciones atípicas adicionales: debe devolver un objeto (o referencia a un objeto) que también tiene un operador de desreferencia de puntero, o debe devolver un puntero que se puede usar para seleccionar a qué apunta la flecha del operador de desreferencia de puntero. ”
Bruce Eckel: Thinking CPP Vol-one : operador->
La funcionalidad adicional se proporciona para mayor comodidad, por lo que no tiene que llamar
a->->func();
Simplemente puede hacer:
a->func();
Eso hace que operator -> sea diferente de las otras sobrecargas de operadores.

6502
No puede sobrecargar el acceso de miembros .
(es decir, la segunda parte de lo que ->
lo hace). Sin embargo, puede sobrecargar el unario desreferenciar operador *
(es decir, la primera parte de lo que ->
lo hace).
El C++ ->
operador es básicamente la unión de dos pasos y esto es claro si piensas que x->y
es equivalente a (*x).y
. C++ le permite personalizar qué hacer con el (*x)
parte cuando x
es una instancia de tu clase.
La semántica para ->
la sobrecarga es algo extraña porque C++ le permite devolver un puntero normal (que se usará para encontrar el objeto apuntado) o devolver una instancia de otra clase si esta clase también proporciona un ->
operador. Cuando en este segundo caso la búsqueda del objeto desreferenciado continúa desde esta nueva instancia.
los ->
El operador no sabe a qué miembro se está apuntando, solo proporciona un objeto para realizar el acceso real al miembro.
Además, no veo ninguna razón por la que no pueda proporcionar versiones constantes y no constantes.
Cuando sobrecarga operator->() (aquí no se pasan argumentos), lo que el compilador realmente hace es llamar -> recursivamente hasta que devuelve un puntero real a un tipo. Luego usa el miembro/método correcto.
Esto es útil, por ejemplo, para crear una clase de puntero inteligente que encapsule el puntero real. Se llama al operador sobrecargado->, hace lo que hace (por ejemplo, bloqueo para seguridad de subprocesos), devuelve el puntero interno y luego el compilador llama a -> para este puntero interno.
En cuanto a la constancia, se ha respondido en los comentarios y otras respuestas (puede y debe proporcionar ambas).
Creo que las preguntas frecuentes de C++ anteriores tocan todas las preguntas que se preguntan en la pregunta anterior.
– Alok Guardar
8 de enero de 2012 a las 13:19
const
y no-const
versiones deoperator->
no son requeridopero proporcionar ambos puede ser útil.– Fred Foo
8 de enero de 2012 a las 13:26
Ver también: yosefk.com/c++fqa/operator.html
– György Andrasek
8 de enero de 2012 a las 13:42
@Als: las preguntas frecuentes no explican cómo sobrecargar
->*
y.*
. De hecho, ¡ni siquiera los menciona! Siento que son demasiado raros para estar en las preguntas frecuentes, pero con gusto vincularía esta pregunta desde las preguntas frecuentes. ¡Por favor, no cierre esto como un engaño de las preguntas frecuentes!– sbi
19 de enero de 2012 a las 11:56
@sbi, simplemente no pude encontrar un enlace a esta pregunta en sus (increíbles) preguntas frecuentes y terminé haciendo una pregunta duplicada. ¿Podrías hacerlo más obvio? (disculpas si ya es obvio).
– Pi
29 de diciembre de 2014 a las 14:18