Plantillas en c ++

Video: Tutorial de C++ en Español # 30 - Plantillas de Función

C ++ es un ejemplo de un lenguaje de programación fuertemente tipado. Es este fuerte-dad escrito que permite a las funciones a ser sobrecargados, como se muestra en el siguiente fragmento de código:

nula grado (Estudiante&) De grado -void (Tierra&) Fn -void (Estudiante& s) {grado (s) -}

C ++ no tiene problemas para comprender que el llamado a grado (s) deben ser dirigidas a la función grado (Estudiante&).

Fuertes fuerzas métodos de escritura a ser sobrecargados que parece el mismo en el nivel C ++, pero son bastante diferentes en su aplicación como en el siguiente ejemplo:

int comparar (int l, int r) {return (l gt; r)? 1: (l lt; r)? -1: 0-} int comparar (doble l, doble r) {return (l gt; r)? 1: (l lt; r)? -1: 0-}

Esta comparar() devuelve un 1 si la izquierda; argumento mano es mayor que la derecha; lado, un -1 si la izquierda; argumento mano es inferior a la derecha; la mano, y un 0 si son iguales. A pesar de la similitud de código fuente, el código de máquina generado por estas dos funciones es muy diferente, debido a diferencias en la forma en que int se implementa frente doble a pie de máquina.

El preprocesador ofrece una manera de evitar este tipo de implementaciones redundantes:

#define COMPARAR (l, r) (((l) gt; (r)) 1:?? ((l) lt; (r)) -1: 0)

Sin embargo, esto adolece de una serie de graves limitaciones - no menos importante de los cuales es la necesidad de la función para encajar en una expresión (en efecto, en una línea). Además, los errores en una macro preprocesador puede conducir a problemas que son difíciles de depurar.

plantillas de funciones

La función de plantilla en C ++ permite al programador para retener las ventajas de tipado fuerte y evitar las limitaciones del preprocesador mediante el uso de un marcador de posición para el tipo. A continuación se definen comparar() por alguna clase no especificada T a ser nombrado más tarde:

modelo  T Comparar (T l, T r) {return (l gt; r)? 1: (l lt; r)? -1: 0-}

Tal definición es conocida como una plantilla de función. Esta plantilla de función - cuyo nombre completo es comparar(T, T) - puede ser convertido en una función real mediante el suministro T:

Video: Curso de C++: Plantillas de Funciones con Tipos Múltiples en C++

plantilla de doble Comparar(doble doble)-

También puede permitir a C ++ para encontrar y crear una instancia de la clase T para usted, ya sea proporcionando una declaración parcial o mediante el uso de la función como se muestra en el siguiente fragmento de código de ejemplo:

plantilla de doble Comparar (doble, doble) -INT main () {cout lt; lt; comparar (0, 0) lt; lt; " "lt; lt; comparar (1.0, 2.0) lt; lt; endl retorno 0-}

Aquí la función comparar (doble, doble) es creado por la declaración inicial, incluso sin el extra después de que el nombre de la función. La función comparar (int, int) se crea cuando se utiliza en la instrucción comparar (0, 0).

plantillas de clase

El C ++ función de plantilla permite que las clases que se definen utilizando tipos que se especifican más adelante. Esto resuelve una serie de problemas diferentes en una forma de tipo seguro. Uno de los problemas, aunque lejos de ser el único problema, es la de los contenedores genéricos. (UN envase es una clase que contiene objetos de otra clase).

En los primeros días de C ++, la única manera de crear una clase de contenedor genérico era confiar en el genérico vacío puntero (el puntero de la clase vacío*). Al igual que el #definir “Función” se mencionó anteriormente, este enfoque evitó efectivamente sólido mecanismo de tipificación C ++’s con declaraciones como la siguiente:

Contenedor de clase {public void add (void *) - void * get () - // ... otros miembros ...} - Clase storeStudent recipiente vacío (Estudiante& s) {contenedor.add ((void *)&s) - Estudiante} * getStudent () {return (Estudiante *) container.get () -}

plantillas C ++ permiten al programador para definir una plantilla de clase en el que no se especifica uno o más tipos hasta que se utiliza la clase:

modelo  clase Container {public: void put (T * p) -T * get () -} -

En la práctica, la plantilla de clase primero se debe convertir en una clase real, mediante el suministro de un tipo para T. Se puede usar entonces en condiciones de seguridad de tipo completo:

Envase contenedor-Estudiante-s container.put (&s) -Estudiante * pS = container.get () -

No hay necesidad de definir su propio contenedor de clase de la biblioteca de plantillas estándar proporciona una serie de dichas clases. Por ejemplo, el siguiente fragmento de código crea una lista enlazada de punteros a Estudiante objetos y suma uno al final de la lista:

// debe incluir  al inicio del modulelist slist-Student * pS = new Estudiante () - sList.push_back (&s) -

Muchas de las clases que se utiliza todos los días son, de hecho, las instancias de plantillas de clase. El ejemplo más común es cuando istream y ostream se utilizan para la entrada y salida estándar.

iteradores

Aunque no son directamente parte de la función de plantilla, iteradores proporcionar una manera estándar para acceder a los diferentes tipos de contenedores disponibles en la Biblioteca de plantillas estándar. Todos los contenedores proporcionan un método que devuelve un iterador para el comienzo del recipiente y una manera de comprobar cuando el iterador está en el extremo del recipiente (esto incluye recipientes no ordenados para los que ‘comienzo’ y ‘fin’ es un concepto al azar). El iterador sí mismo proporciona al menos dos métodos: uno para devolver el objeto actual y uno para evitar el iterador al siguiente objeto.

El código siguiente itera a través de una colección de punteros a Estudiante objetos. Este mismo código funciona independientemente de los cuales uno de los muchos tipos de envases a los que decide utilizar:

// displayAllStudents - iterar a través de una lista de Estudiantes- // invocar el método toString () // método de displayAllStudents eachvoid (lista& slist) {for (iter auto = sList.begin (!) - iter = sList.end () - iter ++) {Student * pS = * iter-cout lt; lt; pS-gt; toString () lt; lt; endl-}}

(En este ejemplo se asume que la clase Estudiante incluye un método Encadenar() que devuelve una representación de caracteres de un estudiante.)

Esta función utiliza el empezar() método para volver un iterador que apunta al primer elemento del recipiente. Los itera función a través del recipiente hasta los puntos iterador para fin() que se refiere al miembro después de la última miembro en el recipiente. El operador de incremento mueve el iterador al siguiente miembro en el recipiente mientras que el operador * devuelve el objeto apuntado por el iterador.

los auto palabra clave dice declarar iter a ser del tipo devuelto por sList.begin (). Esto es una extensión de C ++ añadido por la norma 2011. Sin auto, Me hubiera declarado iter a ser de tipo lista::const_iterador.

Artículos Relacionados