BUSCAR
INDICE
INDICE DEL TEMA
OBJETIVOS
TEORIA
PALABRAS RESERVADAS
GLOSARIO
EJERCICIOS
RESUELTOS
AUTOEVALUACION
PROPUESTOS
ERRORES
ESTADISTICAS
INICIO
FAQS
LINKS
RECOMIENDANOS
QUIENES SOMOS
MAPA DEL WEB
COLABORAR
Tema 18 Clases: Definiciones
Teoría: Clase sin secciones privadas: struct

Una clase sin secciones privadas es aquella en la que no se aplica la encapsulación. Esta posibilidad no es muy interesante en la programación habitual, pero puede servir de introducción a las clases.

Una estructura sencilla podría ser la siguiente (en este caso C y C++ coinciden):

struct C_Cuenta {

double Saldo;
double Interes;

};

A los datos declarados dentro de una estructura se les da el nombre de variables miembro, datos miembro, o simplemente miembros de la estructura. La estructura del ejemplo anterior tiene dos miembros: Saldo e Interes. La visibilidad de estos dos miembros es el bloque encerrado entre las llaves, pero al igual que en C se puede acceder a ellos desde fuera del bloque por medio de los operadores punto (.) y flecha (->).
Para declarar objetos de la estructura C_Cuenta, en C habría que hacer lo siguiente:

struct C_Cuenta c1, c2;

pero al programar en C++ es suficiente con escribir:

C_Cuenta c1, c2;

ya que en C++ una estructura o clase definida por el usuario es como un tipo de variable.

Para acceder a cada una de las variables miembro de la clase se utiliza el operador dot o punto (.), o bien el operador arrow o flecha (->). Así c1.Saldo se refiere a la variable Saldo de c1, y c2.Interes se refiere a la variable Interes de la c2. Este operador tiene precedencia sobre casi todos los demás operadores. De forma análoga, el operador flecha (->) se utiliza cuando se dispone de la dirección de un objeto (en el puntero correspondiente), en lugar del nombre del objeto. Como se verá más adelante, en C++ es mucho más habitual utilizar el operador flecha que el operador punto.

Ya se ha dicho que la principal característica de las clases de C++ era que agrupan datos y funciones. En C++ las estructuras definidas como en el ejemplo anterior son verdaderas clases. Se pueden añadir algunas funciones a la clase anterior para que sea un caso más real. Estas funciones serán los métodos que permitirán interactuar con las variables de esa clase. Así la clase C_Cuenta puede quedar de esta manera:

struct C_Cuenta {

// Variables miembro 13
double Saldo; // Saldo Actual de la cuenta
double Interes; // Interés aplicado
// Métodos 14
double GetSaldo();
double GetInteres();
void SetSaldo(double unSaldo);
void SetInteres(double unInteres);

};

Las definiciones de esas funciones o métodos podrían ser como sigue:

double C_Cuenta::GetSaldo()
{ return Saldo; } // Se obtiene el valor de la variable Saldo

double C_Cuenta::GetInteres()
{ return Interes; // Se obtiene el valor de la variable Interes

void C_Cuenta::SetSaldo(double unSaldo)
{ Saldo = unSaldo; } // Se asigna un valor a la variable Saldo

void C_Cuenta::SetInteres(double unInteres)
{ Interes = unInteres; // Se asigna un valor a la variable Interes

Se puede adelantar ya que las funciones que se acaban de definir van a resultar muy útiles para acceder a la variables miembro de una clase, salvaguardando el principio de encapsulación.

El operador (::) recibe el nombre de operador de resolución de visibilidad (scope resolution operator). La notación double C_Cuenta::GetSaldo() indica que se está haciendo referencia a la función GetSaldo definida como función miembro en la clase C_Cuenta. Mediante esta notación se puede distinguir entre funciones que tengan el mismo nombre pero distintas visibilidades y permite también acceder a funciones desde puntos del programa en que éstas no son visibles.

La definición de las funciones miembro puede estar incluida en la definición de la propia clase, en cuyo caso la clase quedaría como se muestra a continuación:

En el ejemplo anterior aparece ya un pequeño programa principal que utiliza la clase que se acaba de definir.

Se debe distinguir entre los operadores (.) y el (::). El operador punto (.) se utiliza para acceder a una variable o función miembro a partir del nombre de un determinado objeto, mientras que el operador scope resolution (::) sirve para designar a un miembro (variable o función) de una clase en su definición. Recuérdese que el operador (::) permite también hacer referencia a una
variable global desde dentro de una función de una clase que contenga una variable miembro con el mismo nombre.

Se puede ver que una llamada a la función SetInteres() en la forma:

c1.SetInteres(100.0);

es equivalente a la sentencia:

c1.Interes = 100.0;

mientras que una llamada a la función GetSaldo() en la forma:

cash = c2.GetSaldo();

es equivalente a la sentencia:

cash = c2.Saldo;

Esta última forma de acceder a una variable miembro de una clase atenta contra el principio de encapsulación, que es uno de los objetivos más importantes de la programación orientada a objetos.

Un usuario de una clase sólo necesita conocer el interface, es decir, el aspecto externo de la clase, para poder utilizarla correctamente. En otras palabras, le sería suficiente con conocer la declaración de las funciones miembro públicas y el significado de los argumentos, además de las variables miembro públicas, si las hubiera.