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;
}

冀公网安备13050302001966号