📜  C ++中的泛型(1)

📅  最后修改于: 2023-12-03 15:29:43.001000             🧑  作者: Mango

C++中的泛型

C++中的泛型编程是一种强大的编程技术,可以很好地提高代码的复用性和可维护性。具体来说,泛型编程可以让我们编写通用的代码,使它们能够在不同类型和数据结构上工作。在本文中,我们将介绍C++中的泛型编程,包括模板、STL和泛型算法等方面的内容。

模板

C++中的模板是泛型编程的基础,它是一种将类型参数化的机制。它允许我们在编写代码时使用类型作为变量,从而编写通用的代码。模板可以实现类模板和函数模板两种形式,我们可以根据需要选择使用哪一种。

类模板

类模板允许我们定义通用的类,能够处理多个不同类型的变量。在类模板的定义中,我们使用类型参数来代替实际的类型。例如:

template<typename T>
class MyArray {
public:
    MyArray(int size) : data(new T[size]), size(size) {}
    T& operator[](int index) { return data[index]; }

private:
    T* data;
    int size;
};

上述代码中,MyArray 是一个类模板,它使用类型参数 T 来代表数组元素的类型。我们可以使用这个模板来创建多种不同类型的数组,如下所示:

MyArray<int> arr1(10);
MyArray<double> arr2(5);
函数模板

函数模板是定义通用函数的一种方式,它们能够处理多个不同类型的参数。在函数模板的定义中,我们同样使用类型参数来实现类型的参数化。例如:

template<typename T>
T Max(T a, T b) {
    return a > b ? a : b;
}

上述代码中,Max() 是一个函数模板,它使用类型参数 T 来代表参数的类型。我们可以使用这个模板函数来求解不同类型的参数的最大值,如下所示:

int max_int = Max(3, 5);
double max_double = Max(3.0, 5.0);
STL

STL是C++标准库中的一个重要组成部分,它提供了许多泛型算法和容器的实现。STL中的算法和容器都是通用的,能够处理不同类型和数据结构的数据。

容器

STL中的容器是一种通用的数据结构,能够用来存储和操作多种不同类型的数据。STL中提供了许多不同的容器,包括数组、链表、栈、队列、集合、映射等等。其中,最常用的容器是 vectormap

vector 是一个动态数组结构,能够存储多个元素,支持快速的随机访问和尾部插入。例如:

std::vector<int> nums = {1, 2, 3, 4, 5};
nums.push_back(6);
for (int i = 0; i < nums.size(); ++i) {
    std::cout << nums[i] << " ";
}

map 是一个关联数组(键值对)结构,能够存储多个映射,支持快速的查找和插入。例如:

std::map<string, int> score = {
    {"Alice", 90},
    {"Bob", 85},
    {"Charlie", 95},
};
score["Daniel"] = 80;
std::cout << score["Charlie"] << std::endl;
算法

STL中的算法是一种通用的计算过程,能够在不同类型和数据结构的数据上进行操作。STL中提供了许多不同的算法,包括排序、查找、复制、合并等等。其中,最常用的算法是 sortfind

sort 是一种排序算法,能够将一个序列按照指定的顺序排序。例如:

std::vector<int> nums = {5, 3, 4, 1, 2};
std::sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); ++i) {
    std::cout << nums[i] << " ";
}

find 是一种查找算法,能够在一个序列中查找某一个值。例如:

std::vector<int> nums = {1, 2, 3, 4, 5};
auto it = std::find(nums.begin(), nums.end(), 3);
if (it != nums.end()) {
    std::cout << "Found at index " << it - nums.begin() << std::endl;
} else {
    std::cout << "Not found!" << std::endl;
}
泛型算法

泛型算法是一种将算法抽象化的方法,能够在不同类型和数据结构的数据上进行操作。泛型算法可以被看作是STL中算法机制的推广和扩展,它们能够在不同迭代器上工作,并且能够接受仿函数(包括函数指针、函数对象和Lambda表达式等)作为参数。

迭代器

迭代器是C++中承载容器数据的对象接口,它是泛型算法的重要组成部分。迭代器提供了一组操作接口,包括可以访问元素、移动指针位置、比较等等。通常,迭代器被分为五类,分别是:

  • 输入迭代器(input iterator),是一种能够从容器中读取元素的迭代器;
  • 输出迭代器(output iterator),是一种能够向容器中写入元素的迭代器;
  • 前向迭代器(forward iterator),是一种可以逐个遍历容器元素的迭代器,能够支持读写操作和移动操作,如 ++*
  • 双向迭代器(bidirectional iterator),是一种不仅支持前向遍历,还支持反向遍历的迭代器,能够支持读写操作、移动操作、递减操作,如 --
  • 随机访问迭代器(random access iterator),是一种能够跳跃式地访问容器元素的迭代器,能够支持读写操作、移动操作、递增操作、递减操作、比较操作,如 +-[]
算法

泛型算法包括STL中提供的一些算法以及用户自定义的仿函数。泛型算法一般有以下几种类型:

  • 非修改性算法:不会修改容器中的元素,如 findcountall_of 等等;
  • 修改性算法:会修改容器中的元素,如 fillreplacereverse 等等;
  • 排序和顺序算法:用于排序和顺序操作,如 sortpartial_sortpartition 等等;
  • 数值算法:对容器中的元素进行数值操作,如 accumulateinner_productpartial_sum 等等。

例如:

std::vector<int> nums = {1, 2, 3, 4, 5};
int sum = std::accumulate(nums.begin(), nums.end(), 0);
std::cout << "Sum: " << sum << std::endl;

上述代码中,accumulate 是一个数值算法,它能够对容器中的元素进行累加操作。

结论

泛型编程是C++中非常重要的编程技术之一,它能够极大地提高代码的复用性和可维护性。本文介绍了C++中的泛型编程机制,包括模板、STL和泛型算法等方面的内容。我们希望,这些内容能够帮助您更好地理解C++中的泛型编程,并且能够在实践中灵活地应用它们。