array 是一个数组,对 C-style 的数组的封装(int arr[] = {10, 20, 30})
为什么C++要对 C 风格的数组进行封装?而不是直接使用C风格数组?
array 是对C数组封装,array 是 C++ 风格定长数组。几乎所有的标准容器(支持遍历的)都可以通过 begin、end 方法来获得,而C风格的数组是没有 begin 和 end 方法。
template<class T> void print_container(T& container) { for (auto it = container.begin(); it != container.end(); ++it) { cout << *it << " "; } cout << endl; } void test01() { vector<int> v = { 10, 20, 30 }; print_container(v); // 恰好我手里容器是原生C风格的容器 // 如何让C风格数组容器拥有C++标准容器拥有的那些方法呢? // C++ 就增加 array 类,该类内部封装了C风格数组。提供了标准容器所需要一些接口。 // int arr[] = { 10, 20, 30 }; // print_container(arr); // 在C++中我们创建定长数组时,就可以使用 array 容器 // array<类型,长度> array<int, 5> arr = { 10, 20, 30, 40, 50 }; print_container(arr); } // 2. array 容器的创建 void test02() { // a1 容器中的元素是没有被初始化 array<int, 5> a1; // array 类内部没有构造函数 // 将 10 20 30 逐个字节拷贝到 array 类内部定义的数组中 array<int, 3> a2 = { 10, 20, 30 }; // int arr[3] = { 10, 20, 30 }; } // 3. array 容器元素访问 void test03() { array<int, 5> arr = { 10, 20, 30, 40, 50 }; // 访问指定位置(下标)的元素 cout << arr[0] << endl; // 下标运算符必须配合类对象才能使用 cout << arr.at(0) << endl; // 假设:是对象指针->at(0) // data 函数返回 array 类内部数组的指针。 cout << arr.data()[0] << endl; cout << get<0>(arr) << endl; // get 是一个全局函数,模板参数编写下标(不能是变量),括号中写容器对象 // 访问首尾元素 // front 返回数组中第一个元素的引用,back 返回数组中最后一个元素的引用 cout << arr.front() << " " << arr.back() << endl; arr.front() = 100; arr.back() = 200; cout << arr.front() << " " << arr.back() << endl; } // 4. array 容器遍历 void test04() { array<int, 5> arr = { 10, 20, 30, 40, 50 }; // for 循环遍历 for (array<int, 5>::iterator it = arr.begin(); it != arr.end(); ++it) cout << *it << " "; cout << endl; for (auto it = arr.begin(); it != arr.end(); ++it) cout << *it << " "; cout << endl; for (auto value : arr) cout << value << " "; cout << endl; // size 返回容器中元素的个数,标准容器的函数 for (size_t i = 0; i < arr.size(); ++i) { cout << arr[i] << " "; // cout << arr.at(i) << " "; // cout << arr.data()[i] << " "; // 以下写法错误,get 函数的模板参数不能是变量,必须是一个编译期常量 // cout << get<i>(arr); } cout << endl; // for_each 算法遍历 for_each(arr.begin(), arr.end(), [](int val) { cout << val << " "; }); cout << endl; } // 5. array 容器填充、交换 void test05() { array<int, 5> arr = { 10, 20, 30, 40, 50 }; // fill 函数可以将容器中所有的值修改指定的某个值 for_each(arr.begin(), arr.end(), [](int val) { cout << val << " "; }); cout << endl; arr.fill(100); for_each(arr.begin(), arr.end(), [](int val) { cout << val << " "; }); cout << endl; // swap 函数交换两个 array 容器中元素的值 array<int, 5> arr2 = { 100, 200, 300, 400, 500 }; arr2.swap(arr); cout << "----------" << endl; for_each(arr.begin(), arr.end(), [](int val) { cout << val << " "; }); cout << endl; for_each(arr2.begin(), arr2.end(), [](int val) { cout << val << " "; }); cout << endl; } // 6. array 容器比较 void test06() { array<int, 5> arr1 = { 10, 20, 30, 40, 50 }; array<int, 5> arr2 = { 10, 20, 30, 40, 50 }; // array 容器直接支持 == 比较,判断两个容器中是否全部的元素都一样 cout << boolalpha << (arr1 == arr2) << endl; } // 假设:容器中存放的是自定义类型。 class Person { public: Person(string name, int age) { m_age = age; m_name = name; } bool operator==(const Person& person) const { return (m_name == person.m_name && m_age == person.m_age); } public: string m_name; int m_age; }; void test07() { // arr1 中的每一个元素和 arr2 中的每一个元素进行比较。 // 问题:编译器不知道 Person 类型对象如何进行比较。 // 给 Person 重载一个比较规则。 array<Person, 2> arr1 = { Person("aaa", 10), Person("bbb", 20) }; array<Person, 2> arr2 = { Person("aaa", 10), Person("bbb", 20) }; cout << boolalpha << (arr1 == arr2) << endl; } // 如果容器中存放的是对象指针,此时应该怎么处理? bool operator==(array<Person*, 2>& arr1, array<Person*, 2>& arr2) { cout << "带对象指针的数组比较" << endl; for (size_t i = 0; i < arr1.size(); ++i) { if (arr1[i]->m_name != arr2[i]->m_name || arr1[i]->m_age != arr2[i]->m_age) { return false; } } return true; } void test08() { // array 比较指针的值是否相等 // 只能是自己重载比较规则 array<Person*, 2> arr1 = { new Person("aaa", 10), new Person("bbb", 20) }; array<Person*, 2> arr2 = { new Person("aaa", 10), new Person("bbb", 20) }; cout << boolalpha << (arr1 == arr2) << endl; }