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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|