C++ 标准库提供了多种容器类型,可以满足不同的需求。以下是一些常用的容器类型。 std::vector: 动态数组,支持快速随机访问和在末尾添加元素,内部使用连续的存储空间。 std::deque: 双端队列,支持在首尾插入和删除元素,内部使用分块的存储空间。 std::list: 双向链表,支持在任意位置插入和删除元素,但无法通过下标直接访问元素。 std::set / std::multiset: 内部自动排序的集合,不可包含重复元素,multiset 可以包含重复元素。 std::map / std::multimap: 内部自动排序的键值对容器,不可包含重复的键,multimap 可以包含重复的键。 这些容器类型都具有各自的优点和适用场景,应根据具体情况进行选择。可以通过查看相关文档和示例代码了解更多细节。 C++ STL库丰富了C++自己的生态。其实,这些容器我们也可以自己实现。在实现容器的时候,可以提高自己的代码能力,帮助我们对容器有一个更好的理解。 实现一个容器需要考虑以下几个方面:
以下是一个简单的示例,实现了一个简单的动态数组容器,支持插入、删除和查找等操作: #include <iostream> #include <memory> #include <stdexcept> using namespace std;
template <typename T> class MyVector { public: // 构造函数 MyVector() : _capacity(10), _size(0) { _data = unique_ptr<T[]>(new T[_capacity]); }
// 带参构造函数,可指定容量的大小 MyVector(int capacity) : _capacity(capacity), _size(0) { _data = unique_ptr<T[]>(new T[_capacity]); }
// 拷贝构造函数 MyVector(const MyVector& other) : _capacity(other._capacity), _size(other._size) { _data = unique_ptr<T[]>(new T[_capacity]); for (int i = 0; i < _size; ++i) { _data[i] = other._data[i]; } }
// 移动构造函数 MyVector(MyVector&& other) noexcept : _capacity(move(other._capacity)), _size(move(other._size)) { _data = move(other._data); other._data = nullptr; }
// 析构函数 ~MyVector() { //这里采用的是智能指针,不需要手动析构 }
// 插入元素 void push_back(T value) { if (_size == _capacity) { resize(_capacity * 2); } _data[_size++] = value; }
// 删除最后一个元素 void pop_back() { if (_size == 0) { throw out_of_range('Vector is empty.'); } _data[--_size] = 0; }
// 删除指定位置的元素 void erase(int index) { if (index < 0 || index >= _size) { throw out_of_range('Index out of range.'); }
for (int i = index; i < _size - 1; ++i) { _data[i] = _data[i + 1]; } _data[--_size] = 0; }
//at 获取指定位置的元素 T& at(int index) { if (index < 0 || index >= _size) { throw out_of_range('Index out of range.'); } return _data[index]; }
//[] 获取指定位置的元素 T& operator[](size_t index) { if (index >= _size) { throw std::out_of_range('index out of range'); } return _data[index]; }
// 获取容器中元素的数量 int size() const { return _size; }
// 获取容器的容量大小 int capacity() const { return _capacity; }
// 判断容器是否为空 bool empty() const { return _size == 0; }
private: // 调整容器的大小 void resize(int newCapacity) { auto newData = unique_ptr<T[]>(new T[newCapacity]);
for (int i = 0; i < _size; ++i) { newData[i] = _data[i]; }
_data = move(newData); _capacity = newCapacity; }
private: unique_ptr<T[]> _data; // 存储数据的指针 int _capacity; // 容量大小 int _size; // 元素数量 };
以上是一个自实现容器的类,我们需要在主函数里面对其进行测试。在测试中,声明一个MyVector 对象,由于是模板类,需要指定其元素类型,类似于STL里面的std::vector<int>。
总结: 这个示例中实现了一个模板类 MyVector,它是一个可变大小的数组容器。其中包含了插入、删除、获取元素等基本操作。 具体来说,可以使用 push_back() 函数向容器末尾添加元素,使用 pop_back() 函数删除最后一个元素,使用 erase() 函数删除指定位置的元素,使用 at() 函数或者下标运算符[]获取指定位置的元素,以及使用 size() 和 capacity() 函数分别获取容器中元素的数量和容量大小。 您可以根据需要对这个示例进行修改和扩展,例如添加更多的操作函数、实现迭代器、支持动态扩容、升序降序排列等等。 |
|