8. Punteros c++
Los punteros
Acaso creiais que en c++ no habia punteros? eso solo ocurre en Java. Los punteros no contienen datos, contienen direcciones de memoria. Para cada tipo de dato hay que definir un puntero.
Con las instrucciones new y delete podemos reservar y liberar espacio libre de memoria. Se utilizan con los punteros (ademas de los objetos) y es muy necesario liberar siempre la memoria con la instruccion delete para evitar memory leaks: espacio de memoria marcados como okupados pero que ya no se usan porque el puntero que les correspondia ahora apunta a otro lado.
Acaso creiais que en c++ no habia punteros? eso solo ocurre en Java. Los punteros no contienen datos, contienen direcciones de memoria. Para cada tipo de dato hay que definir un puntero.
/** * Puntero.cpp * * Clase que muestra las direcciones de variables * Pello Xabier Altadill Izura * Compilar: g++ Puntero.cpp -o Puntero */ #include <iostream.h> int main () { // Creamos varias variables: int pruebaInt = 99, prueba2Int; short pruebaShort = 34; char carac = 'a'; int *puntero = 0; int *punteroNuevo; // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; cout << "Variable prueba2Int: " << prueba2Int << endl; cout << "Direccion prueba2Int: " << &prueba2Int << endl << endl; cout << "Variable pruebaShort: " << pruebaShort << endl; cout << "Direccion pruebaShort: " << &pruebaShort << endl << endl; cout << "Variable carac: " << carac << endl; cout << "Direccion carac: " << &carac << endl << endl; cout << "Variable puntero: " << puntero << endl; // ATENCION, si el puntero no tiene valor dara // SEGMENTATION FAULT y la CAGAREMOS de gordo //cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; puntero = &pruebaInt; cout << "Variable puntero: " << puntero << endl; cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; return 0; }Veamos otro ejemplo...
/** * Puntero2.cpp * * Clase que muestra mas usos de los punteros * Pello Xabier Altadill Izura * Compilar: g++ Puntero2.cpp -o Puntero2 */ #include <iostream.h> // prototipo de funciones que implementamos luego int devuelve(int *punteroInt, int entero); int main () { // Creamos varias variables: int pruebaInt = 99, prueba2Int; short pruebaShort = 34; char carac = 'a'; int *puntero = 0; int *punteroNuevo; // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; cout << "Variable prueba2Int: " << prueba2Int << endl; cout << "Direccion prueba2Int: " << &prueba2Int << endl << endl; cout << "Variable pruebaShort: " << pruebaShort << endl; cout << "Direccion pruebaShort: " << &pruebaShort << endl << endl; cout << "Variable carac: " << carac << endl; cout << "Direccion carac: " << &carac << endl << endl; cout << "Variable puntero: " << puntero << endl; // ATENCION, si el puntero no tiene valor dara // SEGMENTATION FAULT y la CAGAREMOS //cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; puntero = &pruebaInt; cout << "Variable puntero: " << puntero << endl; cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; *puntero = 345; cout << "Variable puntero: " << puntero << endl; cout << "Variable puntero: " << *puntero << endl; cout << "Direccion puntero: " << &puntero << endl << endl; // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; *punteroNuevo = devuelve(puntero,34); cout << " Tras llamada: " << endl; cout << "Variable puntero: " << punteroNuevo << endl; cout << "Variable puntero: " << *punteroNuevo << endl; cout << "Direccion puntero: " << &punteroNuevo << endl << endl; return 0; } int devuelve (int *punteroInt, int entero) { cout << "Variable param. puntero: " << punteroInt << endl; cout << "Variable param. puntero: " << *punteroInt << endl; cout << "Direccion param. puntero: " << &punteroInt << endl << endl; return (*punteroInt) + entero; }new y delete
Con las instrucciones new y delete podemos reservar y liberar espacio libre de memoria. Se utilizan con los punteros (ademas de los objetos) y es muy necesario liberar siempre la memoria con la instruccion delete para evitar memory leaks: espacio de memoria marcados como okupados pero que ya no se usan porque el puntero que les correspondia ahora apunta a otro lado.
/** * Puntero.cpp * * Clase que muestra la okupacion/liberacion de memoria con new y delete * Pello Xabier Altadill Izura * Compilar: g++ Puntero.cpp -o Puntero */ #include <iostream.h> int main () { // Creamos varias variables: int *pruebaInt = new int; short *pruebaShort = new short; pruebaInt = 777; pruebaShort = 23; // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; cout << "Variable pruebaShort: " << pruebaShort << endl; cout << "Direccion pruebaShort: " << &pruebaShort << endl << endl; // Liberamos la memoria delete pruebaInt; delete pruebaShort; // Contra la especulacion del sistema (operativo) // volvemos a oKupar un espacio de memoria int *pruebaInt = new int; short *pruebaShort = new short; pruebaInt = 666; pruebaShort = 21; // quiza tengamos un error, pero se puede comprobar: if ( pruebaInt == NULL || pruebaShort == NULL ) { cout << "Error al reservar memoria" << endl; return 0; } // Ahora las mostramos por pantalla: cout << "Variable pruebaInt: " << pruebaInt << endl; cout << "Direccion pruebaInt: " << &pruebaInt << endl << endl; cout << "Variable pruebaShort: " << pruebaShort << endl; cout << "Direccion pruebaShort: " << &pruebaShort << endl << endl; return 0; }Objetos y punteros Se pueden crear punteros a objetos y atributos que son punteros. Veamos este ejemplo de una clase llamada Objeto:
/** * Objeto.hpp * * Clase que muestra distintos tipos de punteros * que se usan con los objetos * * Pello Xabier Altadill Izura */ #include <iostream.h> // Inicio de la clase class Objeto { private: int *privado; public: int atributo; // Constructor Objeto(); // Constructor Objeto(int atributo); // Destructor ~Objeto(); // Menu tipo case int devuelveAlgo(); };Y su implementacion:
/** * Objeto.cpp * * Clase que muestra distintos tipos de punteros * que se usan con los objetos * Pello Xabier Altadill Izura * Compilar: g++ Objeto.cpp -o Objeto */ #include "Objeto.hpp" // Constructor Objeto::Objeto(){ atributo = 666; } // Constructor Objeto::Objeto(int atributo){ this->atributo = atributo; } // Destructor Objeto::~Objeto(){} // Menu tipo case int Objeto::devuelveAlgo(){ int temp = 0; return temp; } int main () { // Aqui guardaremos el resultado int resultado = 0; cout << " Vamos a jugar con los objetos." << endl; // Creamos la instancia del objeto puntero Objeto objeto = Objeto(); //Creamos un puntero a ese objeto, // pero cuidado, no asignarle un constructor directamente Objeto *objetopuntero; // esto si... objetopuntero = &objeto; // Invocamos los metodos resultado = objeto.devuelveAlgo(); // Observese la diferencia al acceder al atributo publico: cout << " El valor de atributo con Objeto es: " << objeto.atributo << endl; cout << " El valor de atributo con Objeto es: " << objetopuntero->atributo << endl; //return 0; }