28 Declaración de una clase

Ahora va a empezar un pequeño bombardeo de nuevas palabras reservadas de C++, pero no te asustes, no es tan complicado como parece.

La primera palabra que aparece es lógicamente class que sirve para definir una clase y para declarar objetos de esa clase. Su uso es parecido a la ya conocida struct:

class <identificador de clase> [<:lista de clases base>] {
   <lista de miembros>
} [<lista de identificadores de objetos>]; 

La lista de clases base se usa para derivar clases, de momento no le prestes demasiada atención, ya que por ahora sólo declararemos clases base.

La lista de miembros será en general una lista de funciones y datos.

Los datos se declaran del mismo modo en que lo hacíamos hasta ahora, salvo que no pueden ser inicializados, recuerda que estamos hablando de declaraciones de clases y no de definiciones de objetos. En el siguiente capítulo veremos el modo de inicializar las variables de un objeto.

Las funciones pueden ser simplemente declaraciones de prototipos, que se deben definir aparte de la clase pueden ser también definiciones.

Cuando se definen fuera de la clase se debe usar el operador de ámbito "::".

Lo veremos mucho mejor con un ejemplo.

#include <iostream> 
using namespace std;
 
class pareja {
   private:
      // Datos miembro de la clase "pareja"
      int a, b; 
   public:
      // Funciones miembro de la clase "pareja"
      void Lee(int &a2, int &b2);
      void Guarda(int a2, int b2) {
         a = a2;
         b = b2;
      }
};

void pareja::Lee(int &a2, int &b2) {
   a2 = a;
   b2 = b;
}

int main() {
   pareja par1;
   int x, y;
   
   par1.Guarda(12, 32);
   par1.Lee(x, y);
   cout << "Valor de par1.a: " << x << endl;
   cout << "Valor de par1.b: " << y << endl;

   return 0;
}

Nuestra clase "pareja" tiene dos miembros de tipo de datos: a y b.

Y dos funciones, una para leer esos valores y otra para modificarlos.

En el caso de la función "Lee" la hemos declarado en el interior de la clase y definido fuera, observa que en el exterior de la declaración de la clase tenemos que usar la expresión:

void pareja::Lee(int &a2, int &b2)

Para que quede claro que nos referimos a la función "Lee" de la clase "pareja". Ten en cuenta que pueden existir otras clases que tengan funciones con el mismo nombre, y también que si no especificamos que estamos definiendo una función de la clase "pareja", en realidad estaremos definiendo una función corriente.

En el caso de la función "Guarda" la hemos definido en el interior de la propia clase. Esto lo haremos sólo cuando la definición sea muy simple, ya que dificulta la lectura y comprensión del programa.

Además, las funciones definidas de este modo serán tratadas como inline, y esto sólo es recomendable para funciones cortas, ya que, (como recordarás), en estas funciones se inserta el código cada vez que son llamadas.

Especificadores de acceso

Dentro de la lista de miembros, cada miembro puede tener diferentes niveles de acceso.

En nuestro ejemplo hemos usado dos de esos niveles, el privado y el público, aunque hay más.

class <identificador de clase> {
  public:
   <lista de miembros>
  private:
   <lista de miembros>
  protected:
   <lista de miembros>
};

Acceso privado, private

Los miembros privados de una clase sólo son accesibles por los propios miembros de la clase y en general por objetos de la misma clase, pero no desde funciones externas o desde funciones de clases derivadas.

Acceso público, public

Cualquier miembro público de una clase es accesible desde cualquier parte donde sea accesible el propio objeto.

Acceso protegido, protected

Con respecto a las funciones externas, es equivalente al acceso privado, pero con respecto a las clases derivadas se comporta como público.

Cada una de éstas palabras, seguidas de ":", da comienzo a una sección, que terminará cuando se inicie la sección siguiente o cuando termine la declaración de la clase. Es posible tener varias secciones de cada tipo dentro de una clase.

Si no se especifica nada, por defecto, los miembros de una clase son privados.

Palabras reservadas usadas en este capítulo

class, private, protected y public.

Comentarios de los usuarios (8)

Ruben
2010-04-17 12:07:30

¿Se prodria poner algun ejercicio de clases? osea, para entender mejor el tema.

Hasta ahora con los problemas de los temas anteriores todo llegaba a entenderse mejor, y ayudaba mucho a la memoria (eran mas facil de recordarlos) llevar a la practica lo aprendido.

Esteban
2012-04-18 04:56:23

Hola,

¿Podrian explicar el significado de la sentencia "class" en el siguiente ejemplo?

class otraclase;

class derivada : public base
{

public:
        virtual void unafuncion(const otraclase*);

};

Y cual sería la diferencia con incluir la clase "otraclase" de la siguiente forma:

#include "otraclase.hh"

class derivada : public base
{

public:
        virtual void unafuncion(const otraclase*);

};

En ambos casos la clase "otraclase" esta dividida en la cabecera otraclase.hh y la implementacion de sus funciones dentro de otraclase.cc

Muchas gracias y felicitaciones por el curso que esta buenisimo.

Steven R. Davidson
2012-04-18 06:20:06

Hola Esteban,

En la primera versión del ejemplo, indicamos al compilador que el identificador (nombre) 'otraclase' es una clase. No definimos la clase, por lo que es una definición parcial y por tanto, incompleta. Esto se llama "declaración adelantada". En este caso, no hay una clara ventaja de hacer esto.

En la segunda versión, incluyes el contenido del fichero "otraclase.hh", que seguramente contendrá la definición completa de la clase, aunque como dices seguramente no contiene la implementación de cada función miembro, las cuales estarán en el fichero objeto o posiblemente en el fichero fuente, "otraclase.cc".

La idea tras la declaración adelantada es cuando estemos definiendo clases interconectadas. Una definición de una clase requiere el uso de otra clase, pero la definición de esta otra clase requiere el uso de la primera clase. Para ayudar en resolver este tipo de problemas, C++ acepta una declaración adelantada de una clase, y así podemos referirnos a ella sin tener que definir toda la clase previamente. Por ejemplo,

class Jugador
{
  ...
  void atacado( Enemigo *ptr );
  void atacando( Enemigo *ptr );
};

class Enemigo
{
  ...
  void atacado( Jugador *ptr );
  void atacando( Jugador *ptr );
};

El problema como vemos es que para 'Jugador', necesitamos saber qué es 'Enemigo', ya que mencionamos esta entidad, pero el compilador no sabe qué es. No podemos invertir el orden de las definiciones, porque 'Enemigo' requiere 'Jugador', que aún no se habría definido.

La solución es usar una declaración adelantada de 'Enemigo', para que podamos usarla en 'Jugador', para luego definirla completamente. Esto es,

class Enemigo;  // Enemigo es una clase

class Jugador
{
  ...
  void atacado( Enemigo *ptr );
  void atacando( Enemigo *ptr );
};

class Enemigo
{
  ...
  void atacado( Jugador *ptr );
  void atacando( Jugador *ptr );
};

Espero haber aclarado la duda.

Steven

Esteban
2012-04-20 22:35:08

Completamente aclarada, muchísimas gracias...

ergio
2012-05-14 05:22:16

Muestra cómo declarar una clase llamada "Prueba" que contiene dos private int variable llamada: recuento y máx. como deveria mostrar esto en c++.

y este s otro ejemplo

considerin this declaration:

{int i;

public:

sample(int x){i=x

//..

};

sho how to declare a sample objet ti initialize i to 10

pirey
2012-11-05 17:34:00

oyes como puedo realizar un lista dinamica y enforma d directorio con orden alfava vetico la lista deve de ser un clase

Frank F.
2014-03-01 02:25:26

Que tal estimados lectores, vengo por su ayuda, necesito crear un programa "x" usando un struct y una clase final, podrian darme algun ejemplo?(uno de struct y otro de final class) les estaria eternamente agradecido!!!

iv
2015-02-18 15:44:48

tengo una duda con las clases de c++ y es que estoy creando un

programa que tiene esta clase en el archivo Binario.h

class cara_cuadrada {
      
      public:
      
      bool editar;       
      float vertice1_x; float vertice1_y; float vertice1_z;
      float vertice2_x; float vertice2_y; float vertice2_z;
      float vertice3_x; float vertice3_y; float vertice3_z;
      float vertice4_x; float vertice4_y; float vertice4_z;
      
     cara_cuadrada() {
     
     editar = false;
     vertice1_x = 1.0f; vertice1_y = 1.0f; vertice1_z = 1.0f;
     vertice2_x = -1.0f; vertice2_y = 1.0f; vertice2_z = 1.0f;
     vertice3_x = -1.0f; vertice3_y = -1.0f; vertice3_z = 1.0f;
     vertice4_x = 1.0f;  vertice4_y = -1.0f; vertice4_z = 1.0f; 
         
     }    

};
cara_cuadrada idCaraCuadrada[9999999];

y en el archivo main.cpp, uso un temporisador para aumentarle el valor a una variable de mi clase si otra

variable de la clase es true asi

     if(idCaraCuadrada[i].editar == true) {
     idCaraCuadrada[i].vertice1_z += 0.5f;
     } 

y si se preciono la tecla espacio cambio el valor asi

idCaraCuadrada[cara_cuadrada_a_editar].editar = true;

pero no cambia el valor para nada no importa si lo escribo haci

idCaraCuadrada[1].editar = true;

y en el bucle que uso fuciona solo si lo escribo haci

     idCaraCuadrada[i].vertice1_z += 0.5f;

cambia el valor pero si lo escribo 1 en ves de i no lo cambia para nada tambien intente escribir

idCaraCuadrada[1].editar = true;

en el archivo Binario.h al final y me el compilador me lanza

error

 In file included from main.cpp 
 expected constructor, destructor, or type conversion before '.' token 
 expected `,' or `;' before '.' token 
[Build Error]  [main.o] Error 1  

la cosa es que uso la variable editar de la clase para

poder saver a que cara le cambio el valor pero no importa

lo que haga no lo cambia para nada pareciera que el compilador tiene flojera o algo y es que yo no logro ver

el error, me podrian decir que estoy haciendo mal? ya

e consultado varias las paginas de este curso que tengo

guardado en mi pc pero todo parece normal con la forma

en que lo hago ayuda por favor.