¿Por qué 'esto' es un puntero y no una referencia?

183

Estaba leyendo las respuestas a esta pregunta C ++ pros y contras y obtuve esta duda mientras leía los comentarios.

los programadores frecuentemente encuentran confuso que "esto" es un puntero pero no una referencia. otra confusión es por qué "hola" no es de tipo std :: string sino que se evalúa como char const * (puntero) (después de la conversión de matriz a puntero) - Johannes Schaub - litb 22 de diciembre de 08 a 1:56

Eso solo muestra que no usa las mismas convenciones que otros lenguajes (posteriores). - le dorfier 22 de diciembre 08 a las 3:35

Sin embargo, yo llamaría a "esto" una cuestión bastante trivial. Y vaya, gracias por detectar algunos errores en mis ejemplos de comportamiento indefinido. :) Aunque no entiendo qué información sobre el tamaño tiene que ver con nada en el primero. Simplemente no se permite que un puntero apunte fuera de la memoria asignada

¿Es esto un puntero constante? - yesraaj 22 de diciembre '08 a las 6:35

esto puede ser constante si el método es const int getFoo () const; <- en el ámbito de getFoo, "esto" es constante y, por lo tanto, es de solo lectura. Esto evita errores y proporciona cierto nivel de garantía a la persona que llama de que el objeto no cambiará. - Doug T. Dic 22 '08 a las 16:42

no puedes reasignar "esto". es decir, no puede hacer "this = & other;" porque es un valor r. pero esto es de tipo T *, no de tipo T const. es decir, es un puntero no constante. si está en un método const, entonces es un puntero para const. T const. pero el puntero en sí mismo no es constante - Johannes Schaub - litb 22 de diciembre de 08 a las 17:53

piense en "this" de esta manera: #define this (this_ + 0) donde el compilador crea "this_" como un puntero al objeto y convierte "this" en una palabra clave. no puede asignar "this" porque (this_ + 0) es un rvalue. por supuesto que no es así (no existe tal macro), pero puede ayudar a entenderlo - Johannes Schaub - litb 22 de diciembre de 08 a las 17:55

Mi pregunta es, ¿por qué thisun puntero no es una referencia? ¿Alguna razón particular para hacerlo un puntero?


Algunos argumentos adicionales por los que thisser una referencia tendría sentido:

  • Considere Item 1de More Effective C++ : uso referencias cuando se garantiza que tenemos un objeto válido es decir, no un valor NULL (mi interpretación).
  • Además, las referencias se consideran más seguras que los punteros (porque no podemos arruinar la memoria con un puntero perdido).
  • En tercer lugar, la sintaxis para acceder a las referencias ( .) es un poco mejor y más corta que acceder a los punteros ( ->o (*)).
Naveen
fuente
55
@paulm ¿Qué lograría realmente este "pirateo"? ¿No thissiempre evalúa true?
iFreilicht
66
@paulm No creo que sea realmente válido C ++. Invocar métodos en un nullptr a un objeto da como resultado un comportamiento indefinido.
antred
55
@paulm Quizás funcione en algunos casos, pero imagine si el método fue virutal. ¿Cómo podría realizarse una búsqueda de tabla v sin objeto?
Jason Creighton
3
@paulm Si lo has visto en el código de producción, ¡abandona el barco! Eso es UB.
Alice
66
Voy a dejar esto aquí ... (de afxwin2.inl de MFC):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
Christopher Oicles

Respuestas:

176

Cuando el lenguaje evolucionó por primera vez, en las primeras versiones con usuarios reales, no había referencias, solo punteros. Se agregaron referencias cuando se agregó la sobrecarga del operador, ya que requiere referencias para trabajar de manera consistente.

Uno de los usos de thises que un objeto obtenga un puntero a sí mismo. Si fuera una referencia, tendríamos que escribir &this. Por otro lado, cuando escribimos un operador de asignación tenemos que hacerlo return *this, que se vería más simple como return this. Entonces, si tuviera una pizarra en blanco, podría argumentarlo de cualquier manera. Pero C ++ evolucionó gradualmente en respuesta a los comentarios de una comunidad de usuarios (como las cosas más exitosas). El valor de la compatibilidad con versiones anteriores supera por completo las ventajas / desventajas menores derivadas de thisser una referencia o un puntero.

Daniel Earwicker
fuente
44
Bueno, a menudo también es útil que un objeto obtenga una referencia a sí mismo. Yo diría que es un uso más común. De todos modos, la razón principal es como usted dijo, las referencias no existían cuando crearon el puntero 'this'.
jalf
20
Y, si esto fuera una referencia, sería difícil sobrecargar operator &para hacer algo útil. Tendría que haber una sintaxis especial para obtener la dirección de esto que no pasaría operator &.
Omnifarioso
10
@conio: ¡es posible que desee comprobar eso la próxima vez que esté cerca de un compilador de C ++! :) Algo así como:int n = 5; int &r = n; int *p = &r; std::cout << *p;
Daniel Earwicker
14
@Omnifarious, podría escribir &reinterpret_cast<char&>(this);para obtener la dirección real de sobrecarga operator&(de hecho, esto es algo que boost::addressofhace).
Johannes Schaub - litb
9
Como realmente no tiene ningún sentido thisser nulo, me parece que una referencia es realmente más adecuada.
Ponkadoodle
114

Un poco tarde para la fiesta ... Directamente de la boca del caballo, esto es lo que Bjarne Stroustrup tiene que decir (que esencialmente se repite o se toma del libro "Diseño y evolución de C ++"):

¿Por qué " this" no es una referencia?

Porque "esto" se introdujo en C ++ (realmente en C con clases) antes de que se agregaran referencias. Además, elegí " this" para seguir el uso de Simula, en lugar del uso (posterior) de Smalltalk de "self".

Michael Burr
fuente
2
Sí, self hubiera sido bueno para mantener la coherencia con otros idiomas, bueno.
Pilkch