Clases y objetos

Esta semana hemos visto en las clases teóricas el cómo crear clases, y, a partir de ellas, crear objetos.

Las clases sirven como plantillas de las cuales se crean objetos iguales entre sí en cuanto a comportamiento, pero que son distintos en cuanto a su estado.

Siendo muy pragmático, la clase es como una struct, con dos diferencias principales: todos los miembros de la struct son privados por defecto, y además, dentro de una clase pueden empaquetarse funciones además de datos.


class Contador {
private:
    int contador;
public:
    Contador(int c) : contador( c )
        {}
    ~Contador()
        {}
    int getContador()
        { return ++contador; }
};


La clase Contador es un pequeño ejemplo. Tiene un atributo private (la visibilidad por defecto, que indica visibilidad nula), que lleva una cuenta incremental.
La parte pública suele estar formada por funciones miembros tan solo. Estas funciones acceden a los atributos como si fueran variables locales de las mismas, y los cambios que hagan sobre ellos permanecen.

Constructores y destructores

Unas funciones miembro especiales son los constructures y los destructores: los primeros se ejecutan justo después de haber reservado memoria para el objeto, mientras que los segundos se ejecutan justo antes de que se libere la memoria reservada para ese objeto, es decir, se destruya el objeto. Ninguno de los dos devuelve ningún valor, aunque el constructor sí puede tomar parámetros.

Los constructores juegan dos papeles esenciales: asignar memoria a los atributos para el comienzo adecuado de la vida del objeto, o reservar algún recurso (memoria, archivos, sockets ...). El único papel que juega el destructor es liberar recursos, si es que en el constructor se ha reservado alguno.

Un pequeño ejemplo que emplea la clase creada más arriba:


int main()
{
    Contador c1;
    Contador c2( 10 );

    for(int n = 0; n < 10; ++n) {
        cout << c1.getContador() << ',' << d2.getContador() << endl;
    }
}

Ejercicio de objetos

Supongamos que queremos crear una clase que lleve información sobre una persona.
¿Cómo crearíamos esa clase Persona en C++?

La información mínima de la persona sería:
- nombre
- apellidos
- dni
- e.mail
- direccion
- telefono

Es necesario: crear un constructor adecuado y unas funciones miembro que permitan leer esos datos.

Solución

La creación de la clase Persona es bastante sencilla:

class Persona {
private:
    string nombre;
    string apellidos;
    string dni;
    string eMail;
    string telefono;
public:
    Persona(const string &n, const string &a, const string &d, const string &e, const string &t)
        : nombre(n), apellidos(a), dni(d), eMail(e), telefono(t)
        {}
    const string &geNombre() const
        { return nombre; }
    void setNombre(const string &n)
        {  nombre = n; }

    const string &getApellidos() const
        { return apellidos; }
    void setApellidos(const string &a)
        { apellidos = a; }

    const string &getDni() const
        { return dni; }
    void setDni(const string &d)
        { dni = d; }

    const string &getEmail() const
        { return eMail; }
    void setEmail(const string &e)
        { email = e; }

    const string &getTelefono() const
        { return telefono; }
    void setTelefono(const string &t)
        { telefono = t; }
};

Para poder utilizar esta clase, sólo es necesario invocar al constructor debidamente:

int main()
{
     Persona p( "Baltasar", "García Perez-Schofield", "11222333Y", "jbgarcia@nospam.uvigo.es", "988387028" );
     cout << "Persona: " << p.getApellidos() << ',' << p.getNombre() << endl;
}