lunes, 19 de septiembre de 2011

Plantillas en C++

En esta ocasión voy a mostrar un par de ejemplos de uso de plantillas en C++. Las plantillas son el modo de crear clases genéricas en C++ y, como vais a ver, pueden resultar muy útiles. Yo he estado viendo unos vídeos de una asignatura de la universidad de Stanford en la que trabajan con C++. En esta asignatura tienen una librería de funciones para facilitar a los alumnos el desarrollo de los algoritmos que plantean durante el curso. En los vídeos muestran la definición de varias plantillas pero no su implementación, así que decidí implementar algunos de ellos. En primer lugar creé la plantilla de la clase genérica Vector que se puede ver a continuación.

#include <iostream>
#include <vector>

using namespace std;

//DEFINICIÓN DE LA PLANTILLA VECTOR (le llamo Vecto para no confundir con la
//clase vector de STL)
template <typename ElemType>
class Vecto{
  protected:
    vector<ElemType> v;

  public:
    //Vecto() {}
    Vecto(vector<ElemType> vect) {
        v.assign(vect.begin(),vect.end());
    }
    ~Vecto() {
        v.erase(v.begin(),v.end());
    }

    int size() {
        return v.size();
    }

    bool isEmpty() {
        if (size()>0) return false;
        else return true;
    }

    ElemType getAt(int index) {
        return v.at(index);
    }

    void setAt(int pos, ElemType value) {
        v.insert(pos, value);
    }

    void add(ElemType value) {
        v.push_back(value);
    }

    void insertAt(int pos, ElemType value) {
        setAt(pos, value);
    }

    void removeAt(int pos) {
        v.erase(pos);
    }
};

//EJEMPLO DE USO DE LA PLANTILLA VECTOR

int main()
{
    vector<int> vect;

    for (int i=0; i<10; i++) {
        vect.push_back(i);
    }
    for (int i=0; i<10; i++) {
        cout << "vect[" << i << "]= " << vect.at(i) << endl;
    }

    Vecto<int> v(vect);

    cout << "size: " << v.size() << endl << endl;
    for (int i=0; i<v.size(); i++) {
        cout << "vector[" << i << "]= " << v.getAt(i) << endl;
    }
    return 0;
}
En segundo lugar, os muestro la plantilla definida para definir tablas de valores. En este caso la clase se llama Grid y permite crear una tabla de datos del tipo de datos que el programador decida en el momento de declarar el objeto.

#include <iostream>
#include <vector>

using namespace std;

//DEFINICIÓN DE LA PLANTILLA GRID
template <typename ElemType>
class Grid {
  public:
    Grid() {
        rows=0;
        cols=0;
    }
    Grid(int numRows, int numCols): tabla(numRows){
        rows=numRows;
        cols=numCols;
        for (int i=0; i<numRows; ++i) {
            tabla[i].resize(numCols);
        }
    }
    ~Grid(){}

    const vector<ElemType> & operator[](int r) const {return tabla[r];}
    vector<ElemType> & operator[](int r) {return tabla[r];}

    int numRows() {return rows;}
    int numCols() {return cols;}


    ElemType getAt(int row, int col){
        return tabla[row][col];
    }
    void setAt(int row, int col, ElemType value) {
        tabla[row][col] = value;
    }

    void resize(int numRows, int numCols) {
        rows = numRows;
        cols = numCols;
        tabla.resize(rows);
        for (int i=0; i<numRows; ++i) {
            tabla[i].resize(numCols);
        }
    }
  protected:
    vector<vector<ElemType> > tabla;
    int rows, cols;
};


//EJEMPLO DE USO DE LA PLANTILLA GRID

int main()
{
    Grid<int> A(3,3);

    A[0][0] = 1;
    A[1][1] = 1;
    A[2][1] = 3;

    for (int i=0; i<3; i++) {
        for (int j=0; j<3; j++) {
            cout << A.getAt(i,j) << "  ";
        }
        cout << endl;
    }

    cout << endl << endl;
    A.resize(4,4);
    cout << "Columnas: " << A.numCols() << "    Filas: " << A.numRows() << endl << endl;

    for (int i=0; i<4; i++) {
        for (int j=0; j<4; j++) {
            cout << A.getAt(i,j) << "  ";
        }
        cout << endl;
    }

    return 0;
}

Hay que indicar que pese a que yo he utilizado el tipo int en los ejemplos, es posible utilizar otro tipo de dato u objeto definido previamente.

No hay comentarios:

Publicar un comentario