Plantillas de clase de C++
Plantillas de clases de C++
En este tutorial, aprenderemos sobre plantillas de clase en C++ con la ayuda de ejemplos.
Las plantillas son características poderosas de C++ que nos permiten escribir programas genéricos. Hay dos formas en que podemos implementar plantillas:
- Plantillas de funciones
- Plantillas de clase
De manera similar a las plantillas de funciones, podemos usar plantillas de clases para crear una sola clase para trabajar con diferentes tipos de datos.
Las plantillas de clase son útiles ya que pueden hacer que nuestro código sea más corto y más manejable.
Declaración de plantilla de clase
Una plantilla de clase comienza con la palabra clave template
seguido de los parámetros de la plantilla dentro de <>
que es seguido por la declaración de clase.
template <class T>
class className {
private:
T var;
... .. ...
public:
T functionName(T arg);
... .. ...
};
En la declaración anterior, T
es el argumento de plantilla que es un marcador de posición para el tipo de datos utilizado y class
es una palabra clave.
Dentro del cuerpo de la clase, una variable miembro var y una función miembro functionName()
ambos son del tipo T
.
Creación de un objeto de plantilla de clase
Una vez que hemos declarado y definido una plantilla de clase, podemos crear sus objetos en otras clases o funciones (como el main()
function) con la siguiente sintaxis
className<dataType> classObject;
Por ejemplo,
className<int> classObject;
className<float> classObject;
className<string> classObject;
Ejemplo 1:Plantillas de clases de C++
// C++ program to demonstrate the use of class templates
#include <iostream>
using namespace std;
// Class template
template <class T>
class Number {
private:
// Variable of type T
T num;
public:
Number(T n) : num(n) {} // constructor
T getNum() {
return num;
}
};
int main() {
// create object with int type
Number<int> numberInt(7);
// create object with double type
Number<double> numberDouble(7.7);
cout << "int Number = " << numberInt.getNum() << endl;
cout << "double Number = " << numberDouble.getNum() << endl;
return 0;
}
Salida
int Number = 7 double Number = 7.7
En este programa. hemos creado una plantilla de clase Number
con el código
template <class T>
class Number {
private:
T num;
public:
Number(T n) : num(n) {}
T getNum() { return num; }
};
Observe que la variable num , el argumento del constructor n , y la función getNum()
son del tipo T
, o tener un tipo de devolución T
. Eso significa que pueden ser de cualquier tipo.
En main()
, hemos implementado la plantilla de clase creando sus objetos
Number<int> numberInt(7);
Number<double> numberDouble(7.7);
Observe los códigos Number<int>
y Number<double>
en el código anterior.
Esto crea una definición de clase para cada int
y float
, que luego se utilizan en consecuencia.
Es obligatorio especificar el tipo al declarar objetos de plantillas de clase. De lo contrario, el compilador producirá un error.
//Error
Number numberInt(7);
Number numberDouble(7.7);
Definir un miembro de clase fuera de la plantilla de clase
Supongamos que necesitamos definir una función fuera de la plantilla de clase. Podemos hacer esto con el siguiente código:
template <class T>
class ClassName {
... .. ...
// Function prototype
returnType functionName();
};
// Function definition
template <class T>
returnType ClassName<T>::functionName() {
// code
}
Observe que el código template <class T>
se repite mientras se define la función fuera de la clase. Esto es necesario y es parte de la sintaxis.
Si observamos el código del Ejemplo 1 , tenemos una función getNum()
que se define dentro de la plantilla de clase Number
.
Podemos definir getNum()
fuera de Number
con el siguiente código:
template <class T>
class Number {
... .. ...
// Function prototype
T getnum();
};
// Function definition
template <class T>
T Number<T>::getNum() {
return num;
}
Ejemplo 2:Calculadora simple usando plantillas de clase
Este programa utiliza una plantilla de clase para realizar sumas, restas, multiplicaciones y divisiones de dos variables num1 y num2 .
Las variables pueden ser de cualquier tipo, aunque solo hemos utilizado int
y float
tipos en este ejemplo.
#include <iostream>
using namespace std;
template <class T>
class Calculator {
private:
T num1, num2;
public:
Calculator(T n1, T n2) {
num1 = n1;
num2 = n2;
}
void displayResult() {
cout << "Numbers: " << num1 << " and " << num2 << "." << endl;
cout << num1 << " + " << num2 << " = " << add() << endl;
cout << num1 << " - " << num2 << " = " << subtract() << endl;
cout << num1 << " * " << num2 << " = " << multiply() << endl;
cout << num1 << " / " << num2 << " = " << divide() << endl;
}
T add() { return num1 + num2; }
T subtract() { return num1 - num2; }
T multiply() { return num1 * num2; }
T divide() { return num1 / num2; }
};
int main() {
Calculator<int> intCalc(2, 1);
Calculator<float> floatCalc(2.4, 1.2);
cout << "Int results:" << endl;
intCalc.displayResult();
cout << endl
<< "Float results:" << endl;
floatCalc.displayResult();
return 0;
}
Salida
Int results: Numbers: 2 and 1. 2 + 1 = 3 2 - 1 = 1 2 * 1 = 2 2 / 1 = 2 Float results: Numbers: 2.4 and 1.2. 2.4 + 1.2 = 3.6 2.4 - 1.2 = 1.2 2.4 * 1.2 = 2.88 2.4 / 1.2 = 2
En el programa anterior, hemos declarado una plantilla de clase Calculator
.
La clase contiene dos miembros privados de tipo T
:num1 &num2 y un constructor para inicializar los miembros.
También tenemos add()
, subtract()
, multiply()
y divide()
funciones que tienen el tipo de retorno T
. También tenemos un void
función displayResult()
que imprime los resultados de las otras funciones.
En main()
, hemos creado dos objetos de Calculator
:uno para int
tipo de datos y otro para float
tipo de datos.
Calculator<int> intCalc(2, 1);
Calculator<float> floatCalc(2.4, 1.2);
Esto le pide al compilador que cree dos definiciones de clase para los tipos de datos respectivos durante la compilación.
Plantillas de clase C++ con múltiples parámetros
En C++, podemos usar varios parámetros de plantilla e incluso usar argumentos predeterminados para esos parámetros. Por ejemplo,
template <class T, class U, class V = int>
class ClassName {
private:
T member1;
U member2;
V member3;
... .. ...
public:
... .. ...
};
Ejemplo 3:Plantillas de C++ con varios parámetros
#include <iostream>
using namespace std;
// Class template with multiple and default parameters
template <class T, class U, class V = char>
class ClassTemplate {
private:
T var1;
U var2;
V var3;
public:
ClassTemplate(T v1, U v2, V v3) : var1(v1), var2(v2), var3(v3) {} // constructor
void printVar() {
cout << "var1 = " << var1 << endl;
cout << "var2 = " << var2 << endl;
cout << "var3 = " << var3 << endl;
}
};
int main() {
// create object with int, double and char types
ClassTemplate<int, double> obj1(7, 7.7, 'c');
cout << "obj1 values: " << endl;
obj1.printVar();
// create object with int, double and bool types
ClassTemplate<double, char, bool> obj2(8.8, 'a', false);
cout << "\nobj2 values: " << endl;
obj2.printVar();
return 0;
}
Salida
obj1 values: var1 = 7 var2 = 7.7 var3 = c obj2 values: var1 = 8.8 var2 = a var3 = 0
En este programa, hemos creado una plantilla de clase, llamada ClassTemplate
, con tres parámetros, siendo uno de ellos un parámetro predeterminado.
template <class T, class U, class V = char>
class ClassTemplate {
// code
};
Observe el código class V = char
. Esto significa que V
es un parámetro predeterminado cuyo tipo predeterminado es char
.
Dentro de ClassTemplate
, declaramos 3 variables var1 , var2 y var3 , cada uno correspondiente a uno de los parámetros de la plantilla.
class ClassTemplate {
private:
T var1;
U var2;
V var3;
... .. ...
... .. ...
};
En main()
, creamos dos objetos de ClassTemplate
con el código
// create object with int, double and char types
ClassTemplate<int, double> obj1(7, 7.7, 'c');
// create object with double, char and bool types
ClassTemplate<double, char, bool> obj2(8, 8.8, false);
Aquí,
Objeto | T | U | V |
---|---|---|---|
obj1 | int | double | char |
obj2 | double | char | bool |
Para obj1 , T = int
, U = double
y V = char
.
Para obj2 , T = double
, U = char
y V = bool
.
Lenguaje C