Вы находитесь на странице: 1из 10

Gu de Buen Uso de C++ a

Algoritmos y Estructuras de Datos III - FCEN - UBA http://www.dc.uba.ar/people/materias/aed3/homepage.html

Introduccin o
Una gu sobre cmo usar correctamente C++ para implementar, dif a o cilmente sea completa. La presente gu tiene por nalidad mostrar un costado del C++ a muchas veces desconocido para quien recin comienza a usarlo. e C++ es un lenguaje basado en el lenguaje C. Lo que hace es brindar la posibilidad de usar clases que el C no tiene. Lo primero que debe hacerse es asimilar la idea de que con C++ algunas cosas deber hacerse distintas de an como se har en C. an La gu contiene esencialmente ejemplos y comparaciones de situaciones haa bituales. En los ejemplos hay un // Antes en C cuando se trata de cdigo o que ya no deber usarse en C++. a

Buen uso
Comentarios en el cdigo o Los comentarios son imprescindibles en cualquier lenguaje de programacin. o En el caso de C++ conviene poner un comentario en la declaracin de la clase. o Adems, es muy recomendable poner un comentario en la declaracin de atriba o utos (variables) y mtodos (funciones) de la clase. e Como ejemplo se puede ver el cdigo que hay en el ejemplo de ocultamiento. o Separacin de los header les o Para evitar inclusiones repetidas y recompilaciones una buena prctica es a tener separado el header del contenido de la clase. Recordemos que las clases propias deber incluirse usando comillas (#include "miclase" ) en cambio an las del lenguaje se incluyen con corchetes angulares (#include <string>). Ocultamiento de la representacin o Una de las buenas cosas que provee el C++ es la capacidad de ocultar la representacin de la clase. Esto se logra clasicando atributos y mtodos en las o e siguientes categor as: private: (privado) para que slo sea visible por la clase o protected: (protegido) para que sea visible por la clase y las clases descendientes. public: (pblico) para que sea visible desde cualquier clase. u

Conviene que los atributos de la clase sean privados, para evitar llevar a un objeto a un estado inconsistente. Por tal motivo para cada atributo, cuando corresponda, hay que denir un getter (un mtodo que permite observar el e contenido) y un setter (un mtodo que permite modicar el contenido). e Para evitar confusin conviene distinguir de alguna manera las variables de o instancia de las locales de los mtodos. Una posibilidad podr ser anteponer e a un prejo a las variables de instancia, por ejemplo m o m . #ifndef #dene Punto h Punto h

/** * Representa un punto en el plano */ class Punto { private: /** coordenada X */ double m coordX; /** coordenada Y */ double m coordY; public: /** devuelve la coordenada X */ /** dene la coordenada X */ void setX(double x); /** devuelve la coordenada Y */ double getY(); /** dene la coordenada Y */ void setY(double y); }; #endif Ejemplo de ocultamiento: Punto.h #include "Punto.h" double Punto::getX() { return m coordX; } void Punto::setX(double x) { m coordX = x; } 2

double Punto::getY() { return m coordY; } void Punto::setY(double y) { m coordY = y; } Ejemplo de ocultamiento: Punto.cpp Makele En todos los proyectos conviene tener un archivo integrador que diga cmo o debe compilarse el proyecto. Puede ser un Makele, o un archivo de proyecto. Bool Afortunadamente en C++ se incluye el tipo equivalente al boolean de Pascal o Java, que es el tipo bool. Tiene 2 constantes: true y false. Conviene usar este tipo en vez de enteros. No es recomendable hacer asignaciones dentro de comparaciones. Es fcil a que esto lleve a confusin, sobre todo si el proyecto es mantenido por varias o personas. Constantes Se incluye la posibilidad de declarar constantes usando const. Veamos un ejemplo. En vez de usar el preprocesador para hacer los reemplazos:

// Antes en C #dene MAX SEMANAL 300 simplemente se dene una constante:

const int MAX SEMANAL = 300; Para ver el uso de const podemos ver el ejemplo de memoria dinmica. a Memoria dinmica a Para reemplazar a malloc y free se usan new y delete. Es imprescindible tener presente que durante la ejecucin del programa por cada new que se hizo o en algn momento debe hacerse un delete. Un error que debe evitarse es pedir u memoria con new e intentar devolverla con free. Tambin pueden pedirse e arrays de memoria dinmica, como en el ejemplo a continuacin. a o 3

#include <iostream> #include <string> using namespace std; const int MAX CANTIDAD = 10; void e memdinamica() { string *palote = new string("); string *strVec = new string[MAX CANTIDAD]; strVec[0] = *palote; cout << strVec[0] << endl; for (int i = 1; i < MAX CANTIDAD; i++) { strVec[i] = strVec[i - 1] + *palote; cout << strVec[i] << endl; } delete[] strVec; delete palote; } Ejemplo de memoria dinmica: e memdinamica.cpp a Uso de referencias A diferencia de como se hac en C, en C++ s pueden pasarse objetos por a referencia. Veamos el siguiente ejemplo: // Antes en C #include <stdio.h> /** * Intercambia dos enteros. Hecho con punteros. */ void swap viejo(int* x, int* y) { int z = *x; *x = *y; *y = z; } void e swap viejo() { int a = 1; int b = 2; swap viejo(&a, &b); printf("%d%d\n", a, b); }

// Ahora en C++ #include <iostream> using namespace std; /** * Intercambia dos enteros. Hecho con pasaje de parametros por referencia. */ void swap(int& x, int& y) { int z = x; x = y; y = z; } void e swap() { int a = 1; int b = 2; swap(a, b); cout << a << b << endl; } Ejemplo de pasaje de parmetros por referencia: e swap.cpp a Templates C++ permite denir clases paramtricas. Se usan ampliamente en las Stane dard Libraries. Veamos un ejemplo: #ifndef #dene Capsula h Capsula h

/** * Es un ejemplo de una Capsula. */ template <class T> class Capsula { private: T m contenido; public: /** Muestra el valor del contenido. */ T get(); /** Cambia el valor del contenido. */ void set(T c); }; template <class T> T Capsula<T>::get() { 5

return m contenido; } template <class T> void Capsula<T>::set(T c) { m contenido = c; } #endif Ejemplo de template: Capsula.h. En un template no debe separarse la declaracin de la clase del cuerpo debido o a que el preprocesador completa el template en el momento de la compilacin. o

Las Standard Libraries (STL)


Strings En C un string se toma como un puntero a char, con un NULL terminador al nal. En C++ esto se ha mejorado. Tal vez string es una de las clases ms a usadas. Algunos mtodos utiles: e s.length() : cantidad de caracteres del string s. s[a] : devuelve el char de la posicin a en el string s. o s.substr(a,b) : devuelve un string copia del substring de s determinado desde a, contando b caracteres. s + t: Devuelve un nuevo string que resulta de copiar s y concatenar t atrs. a s = t: Hace una copia de t y se la asigna a s. Veamos un ejemplo de lo que se puede hacer con strings. #include <iostream> #include <string> using namespace std; /** * Ejemplo de uso de string. */ void e string() { string str = "Hello World!"; //muestra Hello. cout << str.substr(0, 5) << endl; //muestra World!. 6

cout << str.substr(6) << endl; //muestra la longitud, esto es 12. cout << str.length() << endl; //muestra el ultimo caracter, es decir !. cout << str[str.length() - 1] << endl; } Ejemplo de string: e string.cpp Streams Los streams (stream es corriente o ujo) son muy usados en C++ , y tienen un comportamiento anlogo al de los usados por los sistemas operativos. a Al igual que en Unix se tiene la consola con: cout: standard output cin: standard input cerr: standard error Pero no solo se puede manejar el ujo de consola, tambin se puede acceder e a archivos mediante streams. Veamos un ejemplo de un programa que muestra su propio cdigo fuente: o #include <fstream> #include <iostream> #include <string> using namespace std;

/** * Agrega un numero de linea i a un renglon s y lo muestra por out. */ void muestraConNumero(ostream& out, int i, string& s) { out << i << \t << s << endl; }

/** * Ejemplo de uso de stream. * Esta funcion muestra el contenido del archivo e stream.cpp. */ void e stream() { ifstream in("e stream.cpp"); if (in.fail()) { cout << "No puedo abrirme."<< endl; 7

} else { cout << "Soy asi:"<< endl; } for (int i = 0; !in.fail(); i++) { string s; getline(in ,s); if (!in.fail()) { muestraConNumero(cout, i, s); } } } Ejemplo de streams con archivos: e stream.cpp. Vectores El vector de C++ permite agregar elementos al comienzo y al nal. Veamos algunos mtodos bastante utiles: e v.size(): tama&ntilde;o del vector v v[i]: i-simo elemento del vector v e v.push back(e) : agrega el elemento e al nal del vector v. v = w : hace una copia de w y la guarda en v. #include #include #include #include <fstream> <iostream> <string> <vector>

using namespace std; /** * Toma un texto e invierte el orden de sus lineas */ void invertirLineas(istream &in, ostream &out) { vector<string> vecEjemplo; while (!in.fail()) { string s; getline(in, s); if (!in.fail()) { vecEjemplo.push back(s); } } for (int i = 0; i < vecEjemplo.size(); i++) { out << vecEjemplo[vecEjemplo.size() - 1 - i] << endl; } } 8

/** * Ejemplo de uso de vector. */ void e vector() { ifstream in("e vector.cpp"); invertirLineas(in, cout); } Ejemplo de vector: e vector.cpp Iteradores En C++ los contenedores tienen iteradores, los cuales permiten ir recorriendo la estructura secuencialmente como si se tratase de una cinta. Si quisiramos e ver los elementos de un vector, en vez de ir proyectando la componente i-sima e del vector, podr amos iterar sobre el vector. Primero se crea y asocia el iterador, se arranca la cinta (con begin()) y se va avanzando (con ++) hasta llegar al ultimo elemento (determinado por end()). #include <iostream> #include <vector> using namespace std; void e iterador() { vector<int> vec; // Se carga el vector con los primeros 5 cuadrados. for (int i = 0; i < 5; i++) { vec.push back(i * i); } // Y ahora se itera por el vector para mostrarlo. vector<int>::iterator itvec; for (itvec = vec.begin(); itvec != vec.end(); ++itvec) { cout << << *itvec; } cout << endl; } Ejemplo de uso de iteradores: e iterador.cpp

Diferencia de versiones
Lamentablemente hay varias versiones de C++ que son muy similares pero no completamente compatibles. Uno de los ms aceptados es el ANSI C++. a En otras versiones de C++ el siguiente fragmento evitar la compilacin del a o programa: 9

for (int i cout } for (int i cout }

= 0; i < 5; i++) { << i << endl; = 5; i < 10; i++) { << i << endl;

El problema est en que esas versiones expanden el for de la siguiente mana era:

int i = 0; for (; i < 5; i++) ... Para eso un posible parche es denir un nuevo for, con el problema solucionado de esta manera:

#dene for if (true) for #include <iostream> using namespace std; void e for () { for (int i cout } for (int i cout } }

= 0; i < 5; i++) { << i << endl; = 5; i < 10; i++) { << i << endl;

Ejemplo de diferencia con el for: e for.cpp

Referencias
Stroustrup, Bjarne; The C++ Programming Language, Third edition, Addison-Wesley, 1997; http://www.research.att.com/bs/C++.html Bruce Eckel, Chuck Allison; Thinking in C++, Second edition, Volumen 1 y 2, Revision 4.0, MindView, Inc, 2001; http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html (J.M., 2002-04-24, 2002-12-31)

10

Вам также может понравиться