31 c++ clases genéricas

25
4.12.2a Clases genéricas II §1 Las clases genéricas y la organización del código Para la organización de las plantillas de clases genéricas pueden utilizarse las mismas pauta indicada para las funciones genéricas ( 4.12.1b) !ic"ero #nico . !ic"ero combinado . !ic"eros m#ltiples (compilación separada) . §1.1 $l método de fichero único e%ige &ue el compilador encuentre la definición de las plantillas antes de su uso en cada unidad de compilación. Presenta el incon'eniente de &ue las plantilla definidas en un módulo no son 'isibles desde los dem s. esponde al siguiente es&uema template<T> class C1 { // declaración/definición ... // definicion... }; ... int main() { ... C1<char> c1; // uso de una instancia ... } §1.2 $l método de fichero combinado consiste en situar en un fic"ero de cabecera las definiciones de todas las clases genéricas (y de sus funciones*miembro). Posteriormente este fic"ero es incluido en todos los módulos &ue utilicen la clase genérica. La situación &ueda es&uematizada como sigue // cabecera.h #ifndef !T"1 #define !T"1 template<T> class C1 { // declaración ... // definicion... // main.cpp #include < cabecera.h > ... int main() { ... C1<char> c1; ...

Upload: ferbuifo

Post on 04-Oct-2015

6 views

Category:

Documents


0 download

DESCRIPTION

programacion c++

TRANSCRIPT

4.12.2a Clases genricas II1 Las clases genricas y la organizacin del cdigoPara la organizacin de las plantillas de clases genricas pueden utilizarse las mismas pautas indicada para las funciones genricas (4.12.1b): Fichero nico. Fichero combinado. Ficheros mltiples (compilacin separada).

1.1 El mtodo defichero nicoexige que el compilador encuentre la definicin de las plantillas antes de su uso en cada unidad de compilacin. Presenta el inconveniente de que las plantillas definidas en un mdulo no son visibles desde los dems. Responde al siguiente esquema:template class C1 { // declaracin/definicin ... // definicion...};...int main() { ... C1 c1; // uso de una instancia ...}

1.2 El mtodo defichero combinadoconsiste en situar en un fichero de cabecera las definiciones de todas las clases genricas (y de sus funciones-miembro). Posteriormente este fichero es incluido en todos los mdulos que utilicen la clase genrica. La situacin queda esquematizada como sigue://cabecera.h#ifndef PLT_1#define PLT_1 template class C1 { // declaracin ... // definicion... };#endif // PLT_1...// main.cpp#include ...int main() { ... C1 c1; ...}

// modulo-1.cpp#include ...{ ... C1 ch; ...}// modulo-2.cpp#include ...{ ... C1 cx; ...}

De esta forma se garantiza que la plantilla pueda ser utilizada por ms de una unidad de compilacin.

1.3 El mtodo decompilacin separadaconsiste en incluir en un fichero de cabecera las declaraciones de las clases genricas, e incluir este fichero en todos los mdulos de compilacin mediante la oportuna directiva#include. Las definiciones off-line de todos los mtodos van precedidas de la directivaexport, y se incluyen en un fichero que es compilado separadamente://cabecera.h#ifndef C_1#define C_1 template class C1 { // declaracin void C1::f1(); void C1::f2();... };#endif // C_1...// definiciones.cpp#include ...export template void C1::f1() { ... // definicin 1}export template void C1::f2() { ... // definicin 2}...

// modulo-1.cpp#include ...{ ... C1 n1; ...}...// modulo-2.cpp#include ...{ ... C1 cx; ...}...

Desafortunadamente, a la fecha ninguno de los compiladores que hemos utilizado para plataformas PC incluye soporte para el especificadorexporten estas condiciones [1].2El especificadorfriendcon funciones genricasRecordemos quefriendes un especificador de acceso, utilizado para declarar que ciertas funciones o clases (que denominamos "invitadas") tienen acceso al mbito de ciertas clases "anfitrionas" (4.11.2a1). En el captulo correspondiente se explicaron sus caractersticas y las indicaciones pertinentes sobre su uso. Sin embargo, cuando las funcionesfriendde una clase son a su vez funciones genricas ("templates"), su utilizacin requiere algunas cauciones particulares.Para empezar, debemos recordar que los "invitados" (friend) de una clase ordinaria o genrica (plantilla), pueden ser: una funcin, o una clase ordinarias (no genricas); una funcin genrica ("template); una clase genrica; la especializacin de una funcin genrica, y la especializacin de una clase genrica [2].Recordemostambin, que cuando la clase anfitriona es una clase genrica (plantilla), sus propiedades y mtodos son a su vez clases genricas (4.12.2). Como es usual, en estos casos la declaracin de tales mtodos debe hacerse en el cuerpo de la clase genrica, mientras que la definicin puede hacerse dentro (on-line) o fuera (off-line), a continuacin de la anterior. Es el caso esquematizado a continuacin, en el que suponemos una claseArraydestinada a almacenar matrices unidimensionales de elementos de tipo numrico (int,float,long,float*, etc).template class Array { // clase genrica public: Array(); // constructor por defecto Array& operator= (const Array&); // operador de asignacin ...};

template Array::Array() // definicion del constructor /* alguna funcin de T ... */}

template Array& Array::operator= (const Array& ar) { /* alguna funcin de T ... */ ... return *this;}En este ejemplo, tanto el constructor por defecto como el operador de asignacin, se han definido off-line a continuacin del cuerpo de la clase; exactamente igual que en una clase ordinaria, aunque teniendo en cuenta que en esta ocasin, ambos mtodos son a su vez funciones genricas. En realidad, cualquiera que sea la forma de su definicin (on-line u off-line), ambos mtodos estn en el mbito de la clase y pertenecen a ella. Cuando se obtiene una especializacin de la clase genrica. Por ejemplo:Array a1;el compilador conoce el tipo de argumentoque deber utilizar para construir la especializacin de cada mtodo de la clase.

Por su parte, la declaracin de funcionesfriendgenricas, debe hacerse en el cuerpo de la clase anfitriona, pero la definicin debe hacerseantesdel cuerpo de dicha clase. A su vez, los prototipos situados en el cuerpo de la clase, adems del especificadorfriend, deben incluir un indicador del tipo de especializacin que se pretende, mediante el indicadorsituado entre el nombre de la funcin y la lista de argumentos (lo hemos denominadoinstanciacin explcita especfica4.12.1). Es el caso esquematizado a continuacin relativo a la clase anterior, en el que aadimos dos funciones amigas, que son a su vez funciones genricas.template Array operator+ (const Array& ar1, const Array& ar2) { // versin sobrecargada de operator+() para concatenar rrays Array ax(len1 + len2); // Array auxiliar para el resultado ... return ax;}template std::ostream& operator