Вы находитесь на странице: 1из 11

Las clases pueden introducirse de muchas formas, comenzando por la que dice que representan un intento de abstraer el mundo

real. Pero desde el punto de vista del programador clsico, lo mejor es considerarlas como "entes" que superceden las estructuras C en el sentido de que tanto los datos como los instrumentos para su manipulacin (funciones) se encuentran encapsulados en ellos. La idea es empaquetar juntos los datos y la funcionalidad, de ah que tengan dos tipos de componentes (aqu se prefiere llamarlos miembros). Por un lado las propiedades, tambin llamadas variables o campos (fields), y de otro los mtodos, tambin llamados procedimientos o funciones [1]; ms formalmente: variables de clase y mtodos de clase. La terminologa utilizada en la Programacin Orientada a Objetos POO (OOP en ingls), no es demasiado consistente, y a veces induce a cierto error a los programadores que se acercan por primera vez con una cultura de programacin procedural. De hecho, estas cuestiones semnticas suponen una dificultad adicional en el proceso de entender los conceptos subyacentes en la POO, sus ventajas y su potencial como herramienta. Las clases C++ ofrecen la posibilidad de extender los tipos predefinidos en el lenguaje (bsico y derivado). Cada clase representa un nuevo tipo; un nuevo conjunto de objetos caracterizado por ciertos valores (propiedades) y las operaciones (mtodos) disponibles para crearlos, manipularlos y destruirlos. Ms tarde se podrn declarar objetos pertenecientes a dicho tipo (clase) del mismo modo que se hace para las variables simples tradicionales. Considerando que son vehculos para manejo y manipulacin de informacin, las clases han sido comparadas en ocasiones con los sistemas tradicionales de manejo de datos DBMS ("DataBase Management System"); aunque de un tipo muy especial, ya que sus caractersticas les permiten operaciones que estn absolutamente prohibidas a los sistemas DBMS clsicos. La mejor manera de entender las clases es considerar que se trata simplemente de tipos de datos cuya nica peculiaridad es que pueden ser definidos por el usuario. Generalmente se trata de tipos complejos, constituidos a su vez por elementos de cualquier tipo (incluso otras clases). La definicin que puede hacerse de ellos no se reduce a disear su "contenido"; tambin pueden definirse su lgebra y su interfaz. Es decir: como se opera con estos tipos y como los ve el usuario (que puede hacer con ellos). El propio inventor del lenguaje seala que la principal razn para definir un nuevo tipo es separar los detalles poco relevantes de la implementacin de las propiedades que son verdaderamente esenciales para utilizarlos correctament CLASES DERIVADAS. En C++, la herencia simple se realiza tomando una clase existente y derivando nuevas clases de ella. La clase derivada hereda las estructuras de datos y funciones de la clase original. Adems, se pueden aadir nuevos miembros a las clases derivadas y los miembros heredados pueden ser modificados. Una clase utilizada para derivar nuevas clases se denomina clase base, clase padre, superclase o ascendiente. Una clase creada de otra clase se denomina clase derivada o subclase. Se pueden construir jerarquas de clases, en las que cada clase sirve como padre o raz de una nueva clase. Conceptos fundamentales de derivacin C++ utiliza un sistema de herencia jerrquica. Es decir, se hereda una clase de otra, creando nuevas clases a partir de las clases ya existentes. Slo se pueden heredar clases, no funciones ordinarias n variables, en C++. Una clase derivada hereda todos los miembros dato excepto, miembros dato esttico, de cada una de sus clases base. Una clase derivada hereda la funcin miembro de su clase base. Esto significa que se hereda la capacidad para llamar a funciones miembro de la clase base en los objetos de la clase derivada. Los siguientes elementos de la clase no se heredan: 1

Constructores Destructores Funciones amigas Funciones estticas de la clase Datos estticos de la clase Operador de asignacin sobrecargado Las clases base diseadas con el objetivo principal de ser heredadas por otras se denominan clases abstractas. Normalmente, no se crean instancias a partir de clases abstractas, aunque sea posible. La herencia en C++ En C++ existen dos tipos de herencia: simple y mltiple. La herencia simple es aquella en la que cada clase derivada hereda de una nica clase. En herencia simple, cada clase tiene un solo ascendiente. Cada clase puede tener, sin embargo, muchos descendientes. La herencia mltiple es aquella en la cual una clase derivada tiene ms de una clase base. Aunque el concepto de herencia mltiple es muy til, el diseo de clases suele ser ms complejo. Creacin de una clase derivada Cada clase derivada se debe referir a una clase base declarada anteriormente. La declaracin de una clase derivada tiene la siguiente sintaxis:

Class clase_derivada:<especificadores_de_acceso> clase_base {...}; Los especificadotes de acceso pueden ser: public, protected o private. Clases de derivacin Los especificadores de acceso a las clases base definen los posibles tipos de derivacin: public, protected y private. El tipo de acceso a la clase base especifica cmo recibir la clase derivada a los miembros de la clase base. Si no se especifica un acceso a la clase base, C++ supone que su tipo de herencia es privado. Derivacin pblica (public). Todos los miembros public y protected de la clase base son accesibles en la clase derivada, mientras que los miembros private de la clase base son siempre inaccesibles en la clase derivada. Derivacin privada (private). Todos los miembros de la clase base se comportan como miembros privados de la clase derivada. Esto significa que los miembros public y protected de la clase base no son accesibles ms que por las funciones miembro de la clase derivada. Los miembros privados de la clase siguen siendo inaccesibles desde la clase derivada. Derivacin protegida (protected). Todos los miembros public y protected de la clase base se comportan como miembros protected de la clase derivada. Estos miembros no son, pues, accesibles al programa exterior, pero las clases que se deriven a continuacin podrn acceder normalmente a estos miembros (datos o funciones). CREACIN DE UNA CLASE. Sintaxis 2

La construccin de una clase partiendo desde cero, es decir, cuando no deriva de una clase previa, tiene la siguiente sintaxis (que es un caso particular de la sintaxis general: Classkey <info> nombclase {<listamiembros>}; Ejemplo class Hotel { int habitd; int habits; char stars[5]; };

Es significativo que la declaracin (y definicin) de una clase puede efectuarse en cualquier punto del programa, incluso en el cuerpo de otra clase. Salvo que se trate de una declaracin adelantada, el bloque <listamiembros>, tambin denominado cuerpo de la clase, debe existir, y declarar en su interior los miembros que constituirn la nueva clase, incluyendo especificadotes de acceso (explcitos o por defecto) que especifican aspectos de la accesibilidad actual y futura (en los descendientes) de los miembros de la clase. la cuestin de la accesibilidad de los miembros est estrechamente relacionada con la herencia, por lo que hemos preferido trasladar la explicacin de esta importante propiedad al captulo dedicado a la herencia.

Quin puede ser miembro La lista de miembros es una secuencia de declaraciones de propiedades de cualquier tipo, incluyendo enumeraciones, campos de bits etc.; as como declaracin y definicin de mtodos, todos ellos con especificadotes opcionales de acceso y de tipo de almacenamiento. Auto, extern y register no son permitidos; si en cambio static y const. Los elementos as definidos se denominan miembros de la clase. Hemos dicho que son de dos tipo: propiedades de clase y mtodos de clase. Es importante advertir que los elementos constitutivos de la clase deben ser completamente definidos para el compilador en el momento de su utilizacin. Esta advertencia solo tiene sentido cuando se refiere a utilizacin de tipos abstractos como miembros de clases, ya que los tipos simples (preconstruidos en el lenguaje) quedan perfectamente definidos con su declaracin. Ver a continuacin una aclaracin sobre este punto. Ejemplo: Class Vuelo { Char nombre [30]; Int. capacidad; Enum modelo {B747, DC10}; Char origen[8]; Char destino [8]; Char fecha [8]; // Vuelo es la clase // nombre es una propiedad

Void despegue (&operacin}; // despegue es un mtodo Void crucero (&operacin); };

Los miembros pueden ser de cualquier tipo con una excepcin: No pueden ser la misma clase que se est definiendo (lo que dara lugar a una definicin circular), por ejemplo: Class Vuelo { Char nombre [30]; Class Vuelo; ... Sin embargo, si es lcito que un miembro sea puntero al tipo de la propia clase que se est declarando: class Vuelo { Char nombre [30]; Vuelo* ptr; ... En la prctica esto significa que un miembro ptr de un objeto c1 de una clase C, es un puntero que puede sealar a otro objeto c2 de la misma clase. Nota: Esta posibilidad es muy utilizada, pues permite construir rboles y listas de objetos (unos enlazan con otros). Precisamente en el captulo dedicado a las estructuras auto referenciadas, se muestra la construccin de un rbol binario utilizando una estructura que tiene dos elementos que son punteros a objetos del tipo de la propia estructura (recuerde que las estructuras C++ son un caso particular de clases. // Ilegal

Tambin es lcito que se utilicen referencias a la propia clase: class X { int i; char c; public: X(const X& ref, int x = 0); { // Ok. correcto i = ref.i; c = ref.c; };

De hecho, un grupo importante de funciones miembro, los constructorescopia, se caracterizan precisamente por aceptar una referencia a la clase como primer argumento. Las clases pueden ser miembros de otras clases, clases anidadas. Por ejemplo: class X { public: int x; class Xa { public: int x; }; }; Ver aspectos generales en: clases dentro de clases. // clase dentro de clase (anidada) // clase contenedora (exterior)

Las clases pueden ser declaradas dentro de funciones, en cuyo caso se denominan clases locales, aunque presentan algunas limitaciones. Ejemplo: void foo() { ... int x; class C { public: int x; }; } // clase local // funcin contenedora

Tambin pueden ser miembros las instancias de otras clases (objetos): class Vertice { public: int x, y; }; 5

class Triangulo { public: Vertice va, vb, vc; };

// Clase contenedora

// Objetos dentro de una clase

Es pertinente recordar lo sealado al principio: que los miembros de la clase deben ser perfectamente conocidos por el compilador en el momento de su utilizacin. Por ejemplo: class Triangulo { ... Vertice v; }; class Vertice {...}; En estos casos no es suficiente realizar una declaracin adelantada de Vrtice: class Vertice; class Triangulo { public: Vrtice v; }; Class Vrtice {...}; Ya que el compilador necesita una definicin completa del objeto v para insertarlo como miembro de la clase Triangulo. La consecuencia es que importa el orden de declaracin de las clases en el fuente. Debe comenzarse definiendo los tipos ms simples (que no tienen dependencia de otros) y seguir en orden creciente de complejidad (clases que dependen de otras clases para su definicin). Tambin se colige que deben evitarse definiciones de clases mutuamente dependientes: class A { ... B b1; }; class B { 6 // Error: Informacin insuficiente de Vrtice // Error: Vertice no definido

... A a1; }; ya que conduciran a definiciones circulares como las sealadas antes

Los miembros de la clase deben ser completamente declarados dentro del cuerpo, sin posibilidad de que puedan se aadidos fuera de l. Las definiciones de las propiedades se efectan generalmente en los constructores (un tipo de funcinmiembro), aunque existen otros recursos inicializacin de miembros. La definicin de los mtodos puede realizarse dentro o fuera del cuerpo ( funciones inline. Ejemplo: class C { int x; char c; void foo(); }; int C::y; // Error!! declaracin offline

void C::foo() { ++x; } // Ok. definicin offline

Las funcionesmiembro, denominadas mtodos, pueden ser declaradas inline, static virtual, const y explicit si son constructores. Por defecto tienen enlazado externo.

Clases vacas Los miembros pueden faltar completamente, en cuyo caso tendremos una clase vaca. Ejemplo: Class empty {}; La clase vaca es una definicin completa y sus objetos son de tamao distinto de cero, por lo que cada una de sus instancias tiene existencia independiente. Suelen utilizarse como clasesbase durante el proceso de desarrollo de aplicaciones. Cuando se sospecha que dos clases pueden tener algo en comn, pero de momento no se sabe exactamente que. Inicializacin de miembros Lo mismo que ocurre con las estructuras, que a fin de cuentas son un tipo de clase en su declaracin solo est permitido sealar tipo y nombre de los miembros, sin que se pueda efectuar ninguna asignacin, ni an en el caso de que se trate de una constante. As pues, en el bloque <listamiembros> no pueden existir asignaciones. Por ejemplo: class C { 7

... int x = 33; ... }; Las nicas excepciones permitidas son la asignacin a constantes estticas enteras y los enumeradores (ver a continuacin), ya que los miembros estticos tienen unas caractersticas muy especiales. Ejemplo: class C { ... static const int kte = 33; static const kt1 = 33.0 cont int kt2 = 33; static kt3 = 33; // Ok: // Error: No entero // Error: No esttica // Error: No constante // Asignacin ilegal !!

static const int kt4 = f(33); // Error: inicializador no constante };

El sitio idneo para situar las asignaciones a miembros es en el cuerpo de las funciones de clase (mtodos). En especial las asignaciones iniciales (que deben efectuarse al instanciar un objeto de la clase) tienen un sitio especfico en el cuerpo de ciertos mtodos especiales denominados constructores. En el epgrafe "Inicializar miembros" se ahonda en esta cuestin.

Si es posible utilizar y definir un enumerador (que es una constante simblica dentro de una clase. Por ejemplo: class C { ... enum En { E1 = 3, E2 = 1, E3, E4 = 0}; ... };

En ocasiones es posible utilizar un enumerador para no tener que definir una constante esttica. Ejemplo1 Las tres formas siguientes seran aceptables:

class C { static const int k1 = 10; char v1[k1]; enum e {E1 = 10}; char v2[E1]; enum {KT = 20}; char v3[KT]; ... }; Ejemplo2: class CAboutDlg : public CDialog { ... enum { IDD = IDD_ABOUTBOX }; ... }; La definicin de la clase CAboutDlg pertenece a un caso real tomado de MS VC++. El enumerador annimo es utilizado aqu como un recurso para inicializar la propiedad IDD con el valor IDD_ABOUTBOX que es a su vez una constante simblica para el compilador. De no haberse hecho as, se tendra que haber declarado IDD como constante esttica, en cambio la forma adoptada la convierte en una variable enumerada annima que solo puede adoptar un valor (otra forma de designar al mismo concepto). Ejemplo3: Class C { ... enum {CERO = 0, UNO = 1, DOS = 2, TRES = 3}; }; ... void foo(C& c1) { std::cout << c1.CERO; Std::cout << c1.TRES; } // > 0 // > 3

Tngase en cuenta que las clases son tipos de datos que posteriormente tienen su concrecin en objetos determinados. Precisamente una de las razones de ser de las variables de clase, es que pueden adoptar valores 9

distintos en cada instancia concreta de la clase. Por esta razn, a excepcin de las constantes y los miembros estticos, no tiene mucho sentido asignar valores concretos a las variables de clase, ya que los valores concretos los reciben las instancias, bien por asignacin directa, o a travs de los constructores. En el apartado dedicado a Inicializacin de miembros volvemos sobre la cuestin, exponiendo con detalle la forma de realizar estas asignaciones, en especial cuando se trata de constantes. NATURALEZA: TIPO U OBJETOS. Gestin dinmica de tipos. GLib incluye un sistema dinmico de tipos, que no es ms que una base de datos en la que se van registrando las distintas clases. En esa base de datos, se almacenan todas las propiedades asociadas a cada tipo registrado, informacin tal como las funciones de inicializacin del tipo, el tipo base del que deriva, el nombre del tipo, etc. Todo ello identificado por un identificador nico, conocido como GType. Tipos basados en clases (objetos). Para crear instancias de una clase, es necesario que el tipo haya sido registrado anteriormente, de forma que est presente en la base de datos de tipos de GLib!. El registro de tipos se hace mediante una estructura llamada GTypeInfo, que tiene la siguiente forma: Tipos no instanciables (fundamentales). Muchos de los tipos que se registran no son directamente instanciables (no se pueden crear nuevas instancias) y no estn basados en una clase. Estos tipos se denominan tipos fundamentales en la terminologa de GLib! y son tipos que no estn basados en ningn otro tipo, tal y como s ocurre con los tipos instanciables (u objetos). Entre estos tipos fundamentales se encuentran algunos viejos conocidos, como por ejemplo gchar y otros tipos bsicos, que son automticamente registrados cada vez que se inicia una aplicacin que use GLib!. Como en el caso de los tipos instanciables, para registrar un tipo fundamental es necesaria una estructura de tipo GTypeInfo, con la diferencia que para los tipos fundamentales bastar con rellenar con ceros toda la estructura. La mayor parte de los tipos no instanciables estn diseados para usarse junto con GValue, que permite asociar fcilmente un tipo GType con una posicin de memoria. Se usan principalmente como simples contenedores genricos para tipos sencillos (nmeros, cadenas, estructuras, etc.). Implementacin de nuevos tipos. En el apartado anterior se mostraba la forma de registrar una nueva clase en el sistema de objetos de GLib!, y se haca referencia a distintas estructuras y funciones de inicializacin. En este apartado, se va a indagar con ms detalle en ellos. Tanto los tipos fundamentales como los no fundamentales quedan definidos por la siguiente informacin: Tamao de la clase. Funciones de inicializacin (constructores en C++!). Funciones de destruccin (destructores en C++!), llamadas de finalizacin en la jerga de GLib!. Tamao de las instancias. Normas de instanciacin de objetos (uso del operador new en C++!). 10

Funciones de copia. Toda esta informacin queda almacenada, como se comentaba anteriormente, en una estructura de tipo GTypeInfo. Todas las clases deben implementar, aparte de la funcin de registro de la clase (my_object_get_type), al menos dos funciones que se especificaban en la estructura GTypeInfo a la hora de registrar la clase. Estas funciones son: my_object_class_init: funcin de inicializacin de la clase, donde se inicializar todo lo relacionado con la clase en s, tal como las seales que tendr la clase, los manejadores de los mtodos virtuales si los hubiera, etc. my_object_init: funcin de inicializacin de las instancias de la clase, que ser llamada cada vez que se solicite la creacin de una nueva instancia de la clase. En esta funcin, las tareas a desempear son todas aquellas relacionadas con la inicializacin de una nueva instancia de la clase, tales como los valores iniciales de las variables internas de la instancia.

11

Вам также может понравиться