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