viernes, 31 de agosto de 2018

C++ El apuntador This



El apuntador This

En C++, cada objeto tiene acceso a su propia dirección a través de un puntero o apuntador denominado This. Los objetos, utilizan el apuntador this de manera implícita, o sea que internamente el compilador utiliza ese apuntador.
Cuando nosotros escribimos:

cout << variable;

Lo que sucede internamente es:

cout << this -> variable;

También es válido escribir:

cout << (*this).variable;

Las tres instrucciones son equivalentes, siendo la última una forma para des referenciar el objeto.
Con lo cual, ambas instrucciones producen el mismo resultado. Como se puede apreciar, el puntero this, lo precede un operador de flecha (->), este operador es utilizado cuando se trabaja con punteros.
Todo lo anterior es posible con las funciones miembro no static del objeto. Cuando estudiemos los miembros de clase static, veremos que el puntero this no se pasa implícitamente a las funciones miembro static.

Uno de los usos que podemos hacer con el puntero this al utilizarlo de manera explícita, es evitar que un objeto se asigne a si mismo, esto conlleva graves errores si un objeto contiene apuntadores a almacenamiento asignado en forma dinámica. (esto también lo veremos más adelante). Otro uso que también podemos darle al apuntador this es permitir llamadas en cascada a funciones (como veremos en esta oportunidad), como también podemos sobrecargar operadores (que también veremos en esta oportunidad)

Observemos el siguiente ejemplo:

#include<iostream>
using std::cout;
using std::endl;

class Ejemplo{
  public:

    Ejemplo(int num):
      numero(num){}

    void imprimir(){
      cout << numero << endl;
      cout << this -> numero << endl;
      cout << (*this).numero << endl;
    }

  private:
    int numero;
};

int main(){

  Ejemplo mostrar(10);
  mostrar.imprimir();

return 0;
}

Este código produce el siguiente resultado:



Como se puede apreciar, las tres instrucciones muestran el mismo resultado.
Con este ejemplo, quiero dejar en claro que el apuntador this, se puede utilizar en forma implícita y explícita.

Llamada en cascada a funciones

Las llamadas en cascada a funciones, se refieren a realizar varias invocaciones de funciones en la misma instrucción, por ejemplo al crear un objeto:
Obj        b;

Podemos llamar funciones de la siguiente manera:

b.funcion1(5).funcion2(10).funcion3(15);

En futuras lecciones veremos algunos usos que le podemos dar a las llamadas en cascada, lo que importa en esta lección, es ver los usos del puntero this.

En el siguiente ejemplo, se puede apreciar que se encuentra destacadas las funciones set, ya que estas tienen un tipo de retorno (Vehiculo &) que permiten las llamadas en cascada. El tipo de retorno debe ser igual al nombre de la clase. Esto permite devolver una referencia a un objeto de tipo Vehiculo, utilizando la instrucción  return *this

//Interface.h

#include<iostream>
using std::string;
#ifndef INTERFACE_H
#define INTERFACE_H

class Vehiculo{

  public:
    Vehiculo(string = "", string = "", string = "");
    Vehiculo &setTipo(string);
    Vehiculo &setMarca(string);
    Vehiculo &setModelo(string);

    string getTipo()const;
    string getMarca()const;
    string getModelo()const;

    void imprimir()const;

  private:
    string tipo;
    string marca;
    string modelo;
};

#endif // INTERFACE_H


//Funciones.cpp

#include<iostream>
using std::cout;
using std::string;
using std::endl;

#include "Interface.h"

Vehiculo::Vehiculo(string T, string M, string Mo):
  tipo(T), marca(M), modelo(Mo){}

Vehiculo &Vehiculo::setTipo(string T){
  tipo = T;
  return *this;
}
Vehiculo &Vehiculo::setMarca(string M){
  marca = M;
  return *this;
}
Vehiculo &Vehiculo::setModelo(string Mo){
  modelo = Mo;
  return *this;
}

string Vehiculo::getTipo()const{
  return tipo;
}
string Vehiculo::getMarca()const{
  return marca;
}
string Vehiculo::getModelo()const{
  return modelo;
}

void Vehiculo::imprimir()const{
  cout << "Tipo: " << tipo << endl;
  cout << "Marca: " << marca << endl;
  cout << "Modelo: " << modelo << endl;
}

//Inicio.cpp

#include<iostream>
using std::string;

#include "Interface.h"

int main(){

  Vehiculo v;
  v.setTipo("Auto").setMarca("Kia").setModelo("Morning");
  v.imprimir();

return 0;
}

Al compilar y ejecutar este ejemplo, este es el resultado:
 





Esto es todo por ahora, saludos.


Gustavo J. Cerda Nilo, Agosto 2018




1 comentario:

C++ El apuntador This

El apuntador This En C++, cada objeto tiene acceso a su propia dirección a través de un puntero o apuntador denominado This. Lo...