C++ Class Templates
In C++, a class template is a blueprint for creating classes that can operate with any data type. With class templates, you can create generic classes that work with multiple data types, reducing code duplication and improving reusability. This article will explain how class templates work, their benefits, and provide practical examples to illustrate their use.
A class template allows you to define a class with placeholder data types. Instead of specifying a fixed type, class templates enable you to define a class that works with any type. The specific data type is defined when you create an instance of the class.
template <typename T>
class ClassName {
T member_variable;
public:
ClassName(T value);
void display();
};
template <typename T>
: This defines a template with a placeholder type T
.T member_variable
: This is a member variable of type T
.ClassName(T value)
: This constructor takes a parameter of type T
.void display()
: A function that works with the T
type.The T
can be replaced with any data type (like int
, double
, etc.) when the class is instantiated.
Let's create a basic class template that holds a pair of values and prints them.
#include <iostream>
using namespace std;
// Class template to store a pair of values
template <typename T>
class Pair {
private:
T first;
T second;
public:
Pair(T f, T s) : first(f), second(s) {}
void display() {
cout << "First: " << first << ", Second: " << second << endl;
}
};
int main() {
Pair<int> intPair(10, 20); // Pair of integers
Pair<double> doublePair(3.14, 2.71); // Pair of doubles
intPair.display(); // Display integer pair
doublePair.display(); // Display double pair
return 0;
}
Explanation:
Pair
class is a template that holds two values of the same type, T
.intPair
(for integers) and doublePair
(for doubles), each calling the display
function to print the values.Output:
First: 10, Second: 20
First: 3.14, Second: 2.71
Let's create a more complex example of a generic Stack class template that can store elements of any data type.
#include <iostream>
using namespace std;
// Class template for Stack
template <typename T>
class Stack {
private:
T* arr;
int top;
int capacity;
public:
Stack(int size) {
arr = new T[size];
capacity = size;
top = -1;
}
void push(T value) {
if (top == capacity - 1) {
cout << "Stack Overflow!" << endl;
} else {
arr[++top] = value;
cout << value << " pushed into stack" << endl;
}
}
T pop() {
if (top == -1) {
cout << "Stack Underflow!" << endl;
return T(); // Return default value for T
} else {
T poppedValue = arr[top--];
return poppedValue;
}
}
bool isEmpty() {
return top == -1;
}
T peek() {
if (top == -1) {
cout << "Stack is empty!" << endl;
return T(); // Return default value for T
} else {
return arr[top];
}
}
};
int main() {
Stack<int> intStack(5); // Stack of integers
Stack<string> stringStack(3); // Stack of strings
intStack.push(10);
intStack.push(20);
cout << "Popped from int stack: " << intStack.pop() << endl;
stringStack.push("Hello");
stringStack.push("World");
cout << "Popped from string stack: " << stringStack.pop() << endl;
return 0;
}
Explanation:
Stack
class is a generic class that works with any data type T
.intStack
) or strings (stringStack
).push
, pop
, peek
, and isEmpty
functions are used to interact with the stack.Output:
10 pushed into stack
20 pushed into stack
Popped from int stack: 20
Hello pushed into stack
World pushed into stack
Popped from string stack: World
In some cases, you may want a class to accept multiple types. Here's how you can define a class template that works with two different data types.
#include <iostream>
using namespace std;
// Class template with two types
template <typename T, typename U>
class Pair {
private:
T first;
U second;
public:
Pair(T f, U s) : first(f), second(s) {}
void display() {
cout << "First: " << first << ", Second: " << second << endl;
}
};
int main() {
Pair<int, double> pair1(5, 3.14); // Pair of int and double
Pair<string, char> pair2("Hello", 'H'); // Pair of string and char
pair1.display();
pair2.display();
return 0;
}
Explanation:
Pair
class template now accepts two types, T
and U
.int
and double
, and another of type string
and char
.Output:
First: 5, Second: 3.14
First: Hello, Second: H
Sometimes you might want to specialize a class template for a specific type. This can be done through template specialization.
Pair
Class for char
Type
#include <iostream>
using namespace std;
// General template
template <typename T>
class Pair {
private:
T first;
T second;
public:
Pair(T f, T s) : first(f), second(s) {}
void display() {
cout << "First: " << first << ", Second: " << second << endl;
}
};
// Specialization for char type
template <>
class Pair<char> {
private:
char first;
char second;
public:
Pair(char f, char s) : first(f), second(s) {}
void display() {
cout << "Specialized Pair for char: " << first << ", " << second << endl;
}
};
int main() {
Pair<int> intPair(1, 2);
Pair<char> charPair('A', 'B');
intPair.display();
charPair.display();
return 0;
}
Explanation:
Pair
class template for char
types.Pair
class works for all types except char
, which uses the specialized version.Output:
First: 1, Second: 2
Specialized Pair for char: A, B