resueltos relaciones programacion poo orientada objetos herencia entre ejercicios ejemplos ejemplo codigo clases c++ c++-faq

relaciones - programacion orientada a objetos c++ ejemplos



¿Cuándo uso un punto, una flecha o dos puntos dobles para referirme a los miembros de una clase en C++? (2)

Al venir de otros lenguajes derivados de C (como Java o C #) a C ++, al principio es muy confuso que C ++ tenga tres formas de referirse a los miembros de una clase: a::b , ab y a->b . ¿Cuándo uso cuál de estos operadores?

(Nota: se pretende que sea una entrada a las Preguntas frecuentes sobre C ++ de Stack Overflow . Si desea criticar la idea de proporcionar una FAQ en este formulario, la publicación en el meta que inició todo esto sería el lugar para hacerlo. Respuestas a esa pregunta se monitorea en la sala de chat de C ++ , donde comenzó la idea de las preguntas frecuentes en primer lugar, por lo que es muy probable que su respuesta sea leída por aquellos a quienes se les ocurrió la idea.)


Los tres operadores distintos que usa C ++ para acceder a los miembros de una clase o objeto de clase, a saber, el doble punto :: , el punto . , y la flecha -> , se utilizan para tres escenarios diferentes que siempre están bien definidos. Saber esto le permite saber de inmediato bastante acerca de a y b simplemente mirando a a::b , ab , o a->b , respectivamente, en cualquier código que mire.

  1. a::b solo se usa si b es un miembro de la clase (o espacio de nombres) a . Es decir, en este caso a siempre será el nombre de una clase (o espacio de nombres).

  2. ab solo se utiliza si b es un miembro del objeto (o referencia a un objeto) a . Así que para ab , a siempre será un objeto real (o una referencia a un objeto) de una clase.

  3. a->b es, originalmente, una notación abreviada para (*a).b . Sin embargo, -> es el único de los operadores de acceso miembro que puede sobrecargarse, por lo que si a es un objeto de una clase que sobrecarga operator-> (tales tipos comunes son punteros e iteradores inteligentes), entonces el significado es lo que sea el diseñador de clases. implementado. Para concluir: con a->b , si a es un puntero, b será un miembro del objeto al que se refiere el puntero a. Sin embargo, si a es un objeto de una clase que sobrecarga a este operador, entonces se invoca el operador de función de operator->() sobrecargado operator->() .

La letra pequeña:

  • En C ++, los tipos declarados como class , struct o union se consideran "de tipo de clase". Así que lo anterior se refiere a los tres.
  • Las referencias son, semánticamente, alias a los objetos, así que debería haber agregado "o referencia a un puntero" al # 3 también. Sin embargo, pensé que esto sería más confuso que útil, ya que las referencias a los punteros ( T*& ) rara vez se usan.
  • Los operadores de punto y flecha se pueden usar para referirse a miembros de clase estática de un objeto, aunque no sean miembros del objeto. (Gracias a Oli por señalar esto!)

Sugiriendo una alternativa para el punto 3 de sbi

a->b solo se usa si a es un puntero. Es una abreviatura de (*a).b , el miembro b del objeto al que apunta. C ++ tiene dos tipos de punteros, punteros "regulares" e inteligentes. Para punteros regulares como A* a , el compilador implementa -> . Para punteros inteligentes como std::shared_ptr<A> a , -> es una función miembro de la clase shared_ptr .

Justificación: el público objetivo de esta pregunta frecuente no está escribiendo punteros inteligentes. No necesitan saber -> realmente se llama operator->() , o que es el único método de acceso de miembros que se puede sobrecargar.