elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: (TUTORIAL) Aprende a emular Sentinel Dongle By Yapis


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  ¿Por que este codigo funciona?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ¿Por que este codigo funciona?  (Leído 3,545 veces)
4v1dy4

Desconectado Desconectado

Mensajes: 137



Ver Perfil
¿Por que este codigo funciona?
« en: 3 Noviembre 2023, 17:28 pm »

Hice este codigo para experimentar con C++ y entender el tema de los streams:

Código
  1. #include <stdio.h>
  2.  
  3. class Stream {
  4.    public:
  5.        Stream operator<<(const char *);
  6. };
  7.  
  8. Stream Stream::operator<<(const char *s) {
  9.    printf(s);
  10.    return *this;
  11. }
  12.  
  13. int main(int argc, char **argv) {
  14.    Stream cout;
  15.    cout << "Hola" << "\n" << "Adios" << "\n";
  16.    return 0;
  17. }

La cuestion es que funciona pero no entiendo por que.

Esta linea:

Código
  1. cout << "Hola" << "\n" << "Adios" << "\n";

¿No deberia causar un error diciendo que el operador operator<<(const char *, const char *) no existe?

¿Alguien me puede decir que es exactamente lo que ocurren en esa linea?



Creo que entiendo mas o menos lo que ocurre ¿Es esto?

Código
  1. #include <stdio.h>
  2.  
  3. class Stream {
  4.    public:
  5.        Stream operator<<(const char *);
  6. };
  7.  
  8. Stream Stream::operator<<(const char *s) {
  9.    printf(s);
  10.    return *this;
  11. }
  12.  
  13. int main(int argc, char **argv) {
  14.    Stream cout;
  15.    Stream l1, l2, l3;
  16.    l1 = cout << "Hola";
  17.    l2 = l1 << "\n";
  18.    l3 = l2 << "Adios";
  19.    l3 << "\n";
  20.    return 0;
  21. }

Aun si es esto, agradeceria un poco de clarificacion...

Agradezco cualquier ayuda de antemano


« Última modificación: 3 Noviembre 2023, 17:48 pm por 4v1dy4 » En línea

199XAD

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: ¿Por que este codigo funciona?
« Respuesta #1 en: 5 Noviembre 2023, 06:32 am »

Primero hay que tener en claro qué significa la palabra reservada this. Dicho de forma simplificada, es un puntero que apunta al objeto en sí, es decir, mantiene la dirección de memoria del objeto al que hace referencia. Cada objeto tiene una dirección de memoria, al igual que todo tipo primitivo como int, float, etc. Esto puedes verlo más claro si imprimes el valor de this y &obj, donde obj es un objeto de cualquier clase. En código se vería así:
Código
  1. class Foo
  2. {
  3. public:
  4. void printDir()
  5. {
  6. std::printf("%X\n", this);
  7. }
  8. };
  9. int main()
  10. {
  11. Foo obj;
  12. obj.printDir();
  13. std::printf("%X\n", &obj);
  14.        return 0;
  15. }
  16.  

Como verás, la salida es la misma. Pues resulta que esa palabra reservada es una forma cómoda de tener al alcance la dirección de memoria del objeto y así es posible hacer cosas como las que muestras en el ejemplo.
Citar
Stream Stream::operator<<(const char *s) {
    printf(s);
    return *this;
}
Al hacer *this estás haciendo lo que se conoce como desreferenciar el puntero, es decir, accedes al objeto en sí, no a su dirección de memoria, por lo que al hacer return *this y dado el tipo de devuelta de tu función, estás devolviendo una copia del objeto, lo cual no es lo más óptimo, ya que es una copia innecesaria. Ahí justo puedes devolver una referencia. Una referencia y un puntero son prácticamente el mismo concepto, salvo que la referencia tienes que inicializarla donde la defines, además si una función recibe una referencia, no usas el operador &, sino únicamente el nombre del objeto, haciendo que el código se vea menos tedioso. También existe la desreferenciación automática, es decir, si fuera un puntero, harías ptr-> para acceder a un campo o método, pero en una referencia usarías el . como si fuera un objeto normal.
Citar
   cout << "Hola" << "Adios" << "\n";
Esto funciona porque el primer cout (es decir, cout << "Hola" ) se convierte a un objeto, que es una copia del objeto original, después haces << "Adios", ahí sigues teniendo el objeto copia que ya imprimió hola, pero ahora estás llamando con ese objeto otra vez al operador << con el argumento adiós, entonces lo imprimes y así sucesivamente. En resumen, al hacer *this puedes realizar llamadas en cadena, que es lo que estás haciendo en tu código.
Otro ejemplo:
Código
  1. #include <iostream>
  2. class Sum
  3. {
  4. public:
  5. Sum& operator+(int val)
  6. {
  7. sum += val;
  8. return *this;
  9. }
  10. int getSum()
  11. {
  12. return sum;
  13. }
  14. private:
  15. int sum = 0;
  16. };
  17.  
  18. int main()
  19. {
  20.  
  21. Sum s;
  22. s = s + 3 + 3 + 5 + 6;
  23. std::cout << s.getSum() << "\n";
  24.  
  25. return 0;
  26. }


« Última modificación: 5 Noviembre 2023, 06:39 am por 199XAD » En línea

4v1dy4

Desconectado Desconectado

Mensajes: 137



Ver Perfil
Re: ¿Por que este codigo funciona?
« Respuesta #2 en: 5 Noviembre 2023, 15:23 pm »

Citar
al hacer *this puedes realizar llamadas en cadena, que es lo que estás haciendo en tu código.

BINGO.

Muchas gracias por el tiempo que te tomaste para responder.

Efectivamente, es lo que supuse que estaba pasando.

Dices que es una forma poco optima, pero entonces mi pregunta seria, ¿Como entonces seria la forma optima?

Entiendo que cada vez que utilizo el operador <<, esetoy devolviendo el mismo objeto, *this.

Entonces, si estoy devolviendo el mismo objeto todo el tiempo, ¿Por que esta no es una forma optima de hacerlo? y ¿Cual seria entonces la forma optima de hacerlo? ¿Como lo hace, mas o menos en resumen, la libreria estandar de C++?

Gracias de nuevo de antemano,
Un saludo.



Nota: Estoy tomando en cuenta que con "Poco optimo" te refieres a que consume mas memoria de la que seria necesesaria en el caso optimo. No al rendimiento.
« Última modificación: 5 Noviembre 2023, 15:26 pm por 4v1dy4 » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Por qué no me funciona este codigo?
Desarrollo Web
luison 0 2,273 Último mensaje 24 Septiembre 2010, 21:57 pm
por luison
Porque no me funciona este codigo
Programación C/C++
0xDani 3 3,305 Último mensaje 11 Junio 2012, 00:40 am
por 0xDani
No funciona este simple codigo
Programación Visual Basic
luis456 6 5,021 Último mensaje 21 Septiembre 2013, 08:50 am
por luis456
[AYUDA] No funciona este código
ASM
tete55 7 4,360 Último mensaje 10 Diciembre 2014, 22:36 pm
por Vaagish
No me funciona este código
Programación C/C++
Meta 6 3,284 Último mensaje 1 Agosto 2017, 09:44 am
por ivancea96
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines