面试题答案
一键面试函数模板工作原理
- 定义:函数模板是一种通用的函数定义,它使用模板参数来代表不同的数据类型。通过模板参数,一个函数模板可以生成针对多种数据类型的具体函数实例。
- 实例化:当编译器遇到函数模板的调用时,它会根据调用中使用的实际参数类型,生成一个特定类型的函数实例。例如,假设有一个函数模板
template <typename T> T add(T a, T b) { return a + b; }
,当调用add(1, 2)
时,编译器会生成一个int
类型的add
函数实例int add(int a, int b) { return a + b; }
。
类模板工作原理
- 定义:类模板允许定义一个通用的类,其中的成员变量和成员函数的类型由模板参数决定。与函数模板类似,类模板使用模板参数来表示不同的数据类型。
- 实例化:类模板的实例化是在创建对象时进行的。例如,
template <typename T> class Stack { /*... */ };
,当使用Stack<int> s;
时,编译器会生成一个int
类型的Stack
类实例,其中所有与T
相关的类型都被替换为int
。
提高代码复用性的优势
- 减少重复代码:对于不同数据类型但逻辑相同的函数或类,无需为每种数据类型编写重复的代码。例如,对于排序算法,使用函数模板可以为
int
、double
等多种类型使用同一套排序逻辑。 - 增强代码可读性和可维护性:模板使代码更加简洁,并且只需在一处修改通用逻辑,所有实例化都会受到影响。
通用排序算法示例
// 函数模板实现通用的冒泡排序
template <typename T>
void bubbleSort(T arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
T temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
通过这个函数模板,可以对不同类型的数组进行排序,如 int
数组 int arr1[] = {3, 2, 1}; bubbleSort(arr1, 3);
或 double
数组 double arr2[] = {3.1, 2.1, 1.1}; bubbleSort(arr2, 3);
,极大提高了代码复用性。
模板特化及其作用
- 定义:模板特化是针对特定类型对模板进行特殊实现。当模板的通用实现不能满足特定类型的需求时,可使用模板特化。
- 作用:在通用排序算法场景下,如果有一个自定义类,其比较逻辑与普通数值类型不同,就可以使用模板特化。例如:
class MyClass {
public:
int value;
MyClass(int v) : value(v) {}
};
// 模板特化
template <>
void bubbleSort<MyClass>(MyClass arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j].value > arr[j + 1].value) {
MyClass temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
这样,针对 MyClass
类型的数组,就可以使用特化后的 bubbleSort
进行排序,满足了特定类型的特殊需求,同时又保留了通用模板的复用性。