24 - Parte private y public de una clase en C++


Uno de los principios fundamentales de la programación orientada a objetos es el encapsulamiento, esto se logra agrupando una serie de métodos (funciones) y atributos (variables) dentro de una clase.

Hemos visto que una clase tiene dos secciones: una pública y otra privada. Por principios de la programación orientada a objetos los atributos (variables) deben definirse en la parte privada y los métodos dependiendo si queremos que se los pueda llamar desde la main los definiremos de tipo público y si queremos que queden ocultos y solo puedan ser llamados dentro de la clase los definimos en la parte privada.

Problema 1:

Plantear una clase llamada Dado. Definir un atributo valor y tres métodos uno privado que dibuje una línea de asteríscos y otro dos públicos, uno que genere un número aleatorio entre 1 y 6 y otro que lo imprima llamando en este último al que dibuja la línea de asteríscos.

Programa:

#include<iostream>
#include<cstdlib>
#include<ctime>

using namespace std;

class Dado {
private:
    int valor;
    void separador();
public:
    void tirar();
    void imprimir();
};

void Dado::separador()
{
    cout<<"********************";
    cout<<"\n";
}

void Dado::tirar()
{
    srand (time(NULL));
    valor = rand() % 6 + 1;
}

void Dado::imprimir()
{
    separador();
    cout<<valor;
    cout<<"\n";
    separador();
}

int main()
{
    Dado d;
    d.tirar();
    d.imprimir();
    return 0;
}

Este proyecto lo puede descargar en un zip desde este enlace : PartePublicPrivate1.zip

Analicemos como definimos las zonas privadas y públicas de una clase:

class Dado {
private:
    int valor;
    void separador();
public:
    void tirar();
    void imprimir();
};

El atributo valor y el método separador() como están antecedidas por la palabra clave private: significa que desde la main no se podrán acceder, es decir que si escribimos en la main lo siguiente se genera un error sintáctico:

int main()
{
    Dado d;
    d.separador(); //error
    d.valor=9; //error
    return 0;
}

La ventaja de definir los atributos en la zona privada de la clase es que en el caso de haber un error lógico en nuestro programa el mismo queda encapsulado en una clase y es más fácil identificarlo. Por ejemplo pensemos que desarrollamos la clase Dado y cuando imprimimos su valor aparece el 9. Si hemos definido el atributo valor como private luego sólo los métodos de la clase pueden haberlo inicializado y por lo tanto el error está circunscrito a la clase Dado.

Desde la main cuando llamamos a los métodos públicos le antecediemos el nombre del objeto:

int main()
{
    Dado d;
    d.tirar(); //llamada al método tirar del objeto d
    d.imprimir(); //llamada al método imprimir del objeto d
    return 0;
}

Dentro de la clase para llamar a otro método de la misma clase lo hacemos indicando solo el nombre del otro método (dentro del método imprimir llamamos al método separador por su nombre):

void Dado::imprimir()
{
    separador();
    cout<<valor;
    cout<<"\n";
    separador();
}

Importante

Una forma muy común de escribir la declaración de una clase es obviar la palabra clave private:

class Dado {
    int valor;
    void separador();
public:
    void tirar();
    void imprimir();
};

El compilador identifica todos los atributos y métodos que no se les antecede un modificador como private. Es muy común agrupar todos los atributos y métodos privados en la primer parte de la declaración de la clase y luego especificar los métodos públicos luego de la palabra clave public.

El lenguaje C++ inclusive nos permite especificar varias secciones privadas y públicas:

class Dado {
public:
    void tirar();
private:
    int valor;
    void separador();
public:
    void imprimir();
};

De todos modos esta forma de declarar la clase puede no ser muy ordenada.

En este problema tenemos que generar un valor aleatorio entre 1 y 6, utilizamos las funciones srand y rand que se encuentran en las librerías:

#include<cstdlib>
#include<ctime>

La función srand define una semilla inicial para la generación de números aleatorios y le pasamos como parámetro la hora y fecha actual (que la retorna la función time):

    srand (time(NULL));

Luego la función rand() retorna un valor entero entre 0 y RAND_MAX y luego mediante el operador matemático % (resto de una división) podemos acotar los valores enteros a obtener. Le sumamos 1 ya que queremos valores comprendidos entre 1 y 6:

    valor = rand() % 6 + 1;

Problema propuesto

  1. Desarrollar un programa que defina un vector de 5 enteros y muestre el mayor y menor elemento. En el constructor cargarlo con valores aleatorios entre 0 y 10.
    La clase debe utilizar solo la palabra clave public en la declaración de la clase.
Solución
#include<iostream>
#include<cstdlib>
#include<ctime>

using namespace std;

class Vector {
    int vec[5];
public:
    Vector();
    void mayor();
    void menor();
    void imprimir();
};

Vector::Vector()
{
    srand(time(NULL));
    for(int f=0;f<5;f++)
    {
        vec[f]=rand()%11;
    }
}

void Vector::mayor()
{
    int mayor=vec[0];
    for(int f=1;f<5;f++)
    {
        if (vec[f]>mayor)
        {
            mayor=vec[f];
        }
    }
    cout<<"Mayor elemento:";
    cout<<mayor;
    cout<<"\n";
}

void Vector::menor()
{
    int menor=vec[0];
    for(int f=1;f<5;f++)
    {
        if (vec[f]<menor)
        {
            menor=vec[f];
        }
    }
    cout<<"Menor elemento:";
    cout<<menor;
    cout<<"\n";
}

void Vector::imprimir()
{
    for(int f=0;f<5;f++)
    {
        cout <<vec[f]<<"-";
    }
    cout<<"\n";
}

int main()
{
    Vector vector1;
    vector1.imprimir();
    vector1.mayor();
    vector1.menor();
    return 0;
}

Este proyecto lo puede descargar en un zip desde este enlace :PartePublicPrivate2.zip

Retornar