Las plantillas en C++ son una característica poderosa que permite escribir código genérico y reutilizable. Las plantillas permiten definir funciones y clases que operan con cualquier tipo de datos, sin sacrificar la seguridad de tipos. Este tema cubre los conceptos básicos de las plantillas, cómo se utilizan y algunos ejemplos prácticos.
Conceptos Clave
- Plantillas de Función: Permiten definir funciones que pueden operar con diferentes tipos de datos.
- Plantillas de Clase: Permiten definir clases que pueden manejar datos de cualquier tipo.
- Parámetros de Plantilla: Los tipos de datos que se pasan a las plantillas.
- Especialización de Plantillas: Permite definir implementaciones específicas para ciertos tipos de datos.
Plantillas de Función
Definición
Una plantilla de función se define utilizando la palabra clave template
seguida de la lista de parámetros de plantilla entre ángulos (< >
). Aquí hay un ejemplo básico:
#include <iostream> using namespace std; template <typename T> T max(T a, T b) { return (a > b) ? a : b; } int main() { cout << "Max of 3 and 7: " << max(3, 7) << endl; cout << "Max of 3.5 and 2.1: " << max(3.5, 2.1) << endl; cout << "Max of 'a' and 'z': " << max('a', 'z') << endl; return 0; }
Explicación
template <typename T>
: Declara una plantilla con un parámetro de tipoT
.T max(T a, T b)
: Define una funciónmax
que toma dos argumentos del mismo tipoT
y devuelve un valor del mismo tipo.- La función
max
se puede llamar con diferentes tipos de datos (int, double, char) sin necesidad de sobrecargar la función para cada tipo.
Ejercicio Práctico
Ejercicio: Escribe una plantilla de función llamada min
que devuelva el menor de dos valores.
#include <iostream> using namespace std; template <typename T> T min(T a, T b) { return (a < b) ? a : b; } int main() { cout << "Min of 3 and 7: " << min(3, 7) << endl; cout << "Min of 3.5 and 2.1: " << min(3.5, 2.1) << endl; cout << "Min of 'a' and 'z': " << min('a', 'z') << endl; return 0; }
Plantillas de Clase
Definición
Las plantillas de clase permiten definir clases que pueden manejar datos de cualquier tipo. Aquí hay un ejemplo básico de una clase de plantilla para una pila (stack):
#include <iostream> using namespace std; template <typename T> class Stack { private: T* arr; int top; int capacity; public: Stack(int size = 10); ~Stack(); void push(T x); T pop(); T peek(); bool isEmpty(); bool isFull(); }; template <typename T> Stack<T>::Stack(int size) { arr = new T[size]; capacity = size; top = -1; } template <typename T> Stack<T>::~Stack() { delete[] arr; } template <typename T> void Stack<T>::push(T x) { if (isFull()) { cout << "Stack Overflow\n"; return; } arr[++top] = x; } template <typename T> T Stack<T>::pop() { if (isEmpty()) { cout << "Stack Underflow\n"; exit(EXIT_FAILURE); } return arr[top--]; } template <typename T> T Stack<T>::peek() { if (!isEmpty()) { return arr[top]; } else { exit(EXIT_FAILURE); } } template <typename T> bool Stack<T>::isEmpty() { return top == -1; } template <typename T> bool Stack<T>::isFull() { return top == capacity - 1; } int main() { Stack<int> intStack(5); intStack.push(1); intStack.push(2); intStack.push(3); cout << "Top element is: " << intStack.peek() << endl; intStack.pop(); cout << "Top element is: " << intStack.peek() << endl; Stack<string> stringStack(5); stringStack.push("Hello"); stringStack.push("World"); cout << "Top element is: " << stringStack.peek() << endl; stringStack.pop(); cout << "Top element is: " << stringStack.peek() << endl; return 0; }
Explicación
template <typename T>
: Declara una plantilla con un parámetro de tipoT
.class Stack { ... }
: Define una claseStack
que puede manejar datos de cualquier tipoT
.- Los métodos de la clase
Stack
se definen fuera de la clase utilizando la sintaxistemplate <typename T>
yStack<T>::method
.
Ejercicio Práctico
Ejercicio: Escribe una plantilla de clase llamada Queue
que implemente una cola (queue) con las operaciones básicas enqueue
, dequeue
, front
, isEmpty
y isFull
.
#include <iostream> using namespace std; template <typename T> class Queue { private: T* arr; int front; int rear; int capacity; int count; public: Queue(int size = 10); ~Queue(); void enqueue(T x); T dequeue(); T frontElement(); bool isEmpty(); bool isFull(); }; template <typename T> Queue<T>::Queue(int size) { arr = new T[size]; capacity = size; front = 0; rear = -1; count = 0; } template <typename T> Queue<T>::~Queue() { delete[] arr; } template <typename T> void Queue<T>::enqueue(T x) { if (isFull()) { cout << "Queue Overflow\n"; return; } rear = (rear + 1) % capacity; arr[rear] = x; count++; } template <typename T> T Queue<T>::dequeue() { if (isEmpty()) { cout << "Queue Underflow\n"; exit(EXIT_FAILURE); } T item = arr[front]; front = (front + 1) % capacity; count--; return item; } template <typename T> T Queue<T>::frontElement() { if (isEmpty()) { cout << "Queue is empty\n"; exit(EXIT_FAILURE); } return arr[front]; } template <typename T> bool Queue<T>::isEmpty() { return count == 0; } template <typename T> bool Queue<T>::isFull() { return count == capacity; } int main() { Queue<int> intQueue(5); intQueue.enqueue(1); intQueue.enqueue(2); intQueue.enqueue(3); cout << "Front element is: " << intQueue.frontElement() << endl; intQueue.dequeue(); cout << "Front element is: " << intQueue.frontElement() << endl; Queue<string> stringQueue(5); stringQueue.enqueue("Hello"); stringQueue.enqueue("World"); cout << "Front element is: " << stringQueue.frontElement() << endl; stringQueue.dequeue(); cout << "Front element is: " << stringQueue.frontElement() << endl; return 0; }
Especialización de Plantillas
Definición
La especialización de plantillas permite definir implementaciones específicas para ciertos tipos de datos. Aquí hay un ejemplo de una especialización de plantilla para una función max
que maneja cadenas de caracteres (const char*
):
#include <iostream> #include <cstring> using namespace std; template <typename T> T max(T a, T b) { return (a > b) ? a : b; } // Especialización para const char* template <> const char* max<const char*>(const char* a, const char* b) { return (strcmp(a, b) > 0) ? a : b; } int main() { cout << "Max of 3 and 7: " << max(3, 7) << endl; cout << "Max of 3.5 and 2.1: " << max(3.5, 2.1) << endl; cout << "Max of 'a' and 'z': " << max('a', 'z') << endl; cout << "Max of \"apple\" and \"banana\": " << max("apple", "banana") << endl; return 0; }
Explicación
template <>
: Indica una especialización de plantilla.const char* max<const char*>(const char* a, const char* b)
: Define una implementación específica de la funciónmax
para el tipoconst char*
.
Conclusión
Las plantillas en C++ son una herramienta poderosa para escribir código genérico y reutilizable. Permiten definir funciones y clases que pueden operar con cualquier tipo de datos, lo que mejora la flexibilidad y la reutilización del código. En este tema, hemos cubierto los conceptos básicos de las plantillas de función y clase, así como la especialización de plantillas. Con estos conocimientos, estarás mejor preparado para escribir código más eficiente y adaptable.
En el próximo tema, exploraremos el manejo de excepciones en C++, una característica crucial para escribir programas robustos y manejables.
Curso de Programación en C++
Módulo 1: Introducción a C++
- Introducción a C++
- Configuración del Entorno de Desarrollo
- Sintaxis y Estructura Básica
- Variables y Tipos de Datos
- Entrada y Salida
Módulo 2: Estructuras de Control
Módulo 3: Funciones
- Introducción a las Funciones
- Parámetros de Función y Tipos de Retorno
- Sobrecarga de Funciones
- Recursión
Módulo 4: Arreglos y Cadenas
- Introducción a los Arreglos
- Arreglos Multidimensionales
- Introducción a las Cadenas
- Manipulación de Cadenas
Módulo 5: Punteros y Referencias
- Introducción a los Punteros
- Aritmética de Punteros
- Punteros y Arreglos
- Referencias
- Asignación Dinámica de Memoria
Módulo 6: Programación Orientada a Objetos
- Introducción a la POO
- Clases y Objetos
- Constructores y Destructores
- Herencia
- Polimorfismo
- Encapsulación y Abstracción
Módulo 7: Temas Avanzados
- Plantillas
- Manejo de Excepciones
- Entrada/Salida de Archivos
- Biblioteca Estándar de Plantillas (STL)
- Expresiones Lambda
- Multihilo