C++-Project-实现自己手搓的vector
简介
这是一个由编写的C++ vector
模版类,是模仿std::vector
类设计的,与std::vector
有着相像的功能,包括vector
长度的动态分配、自由插入或更改相同类型的元素、迭代器、range-based loop
、使用initializer_list
进行初始化和赋值等功能。
Constructor
vector()
这是默认的构造函数。当未指定大小时,该vector
为空。(即vector内的首地址与末地址(begin()
和end()
)相等。)
Example Code:
1 |
|
在
my::vector
类中并没有有关ostream
的运算符重载,如需要使用ostream
输出一个vector
,需要手动重载相关的运算符。在本文档中的相关实现可见附录。
Output:
1 |
|
vector(const int length)
构造指定长度为length
的vector
。
Example Code:
1 |
|
Output:
1 |
|
vector(const self_type &source)/vector(self_type &&source)
这两个构造函数分别为Copy Constructor
和Move Constructor
。创建一个和Source
所含内容相同的另一个vector
。
需要注意的是,两个
vector
内部所含有的首末指针所含地址不同,二者是互异的,仅仅只是内容相同
Example Code:
1 |
|
Output:
1 |
|
vector(const std::initializer_list<element_type> init_list)
使用initializer_list
构造一个vector
,initializer_list
为在C++11
中引入的概念,该概念允许使用初始化列表的方式初始化一个对象,拓展了C
中只能使用初始化列表初始化一个固定内存区域的语法。
Example Code:
1 |
|
Output:
1 |
|
vector(const_iterator first, const_iterator last)
通过vector
的两个iterator
,进行初始化,初始化的vector包含两个迭代器之间包含的内容,不允许first > last
。
Example Code:
1 |
|
Output:
1 |
|
析构函数
~vector()
该析构函数不需要直接使用。其作用是在析构时,释放掉当前vector
所分配的内存。
获取整体状态
获取当前vector
的整体状态。
bool empty() const
获取当前vector
是否为空(长度/大小是否为0
)。
Example Code:
1 |
|
Output:
1 |
|
size_type size() const/size_type length() const
取得当前vector
的大小/长度
注意:此方法的复杂度为O(1)。
Example Code:
1 |
|
Output:
1 |
|
size_type capacity() const
获取当前vector
在内存中所占的实际容量。
Example Code:
1 |
|
Output:
1 |
|
获取特定元素(的引用)
element_reference operator[](const int index)
按照地址偏移量,给出特定位置元素的引用。(为提高性能,没有范围检查)
Example Code:
1 |
|
Output:
1 |
|
element_reference at(const int index)
按照地址偏移量,给出特定位置元素的引用。
Example Code:
1 |
|
Output:
1 |
|
element_reference front()/const_element_reference front() const
给出该vector
第一个元素的引用。
Example Code:
1 |
|
Output:
1 |
|
element_reference back()/const_element_reference back() const
给出该vector
最后一个元素的引用。
Example Code:
1 |
|
Output:
1 |
|
iterator begin() const
给出第一个元素的迭代器。
Example Code:
1 |
|
Output:
1 |
|
iterator end() const
给出一个迭代器,指向最后一个元素之后的一个位置。
Example Code:
1 |
|
Output:
1 |
|
比较运算符
bool operator==(const self_type &rhs) const/bool operator!=(const self_type &rhs) const
比较两个vector
在长度和每个元素上是否都相等。
Example Code:
1 |
|
Output:
1 |
|
Range-Based Loop
使用C++11提供的新语法,进行for循环。
具体实现方式可以参考链接,简单来说,需要在容器内实现一个
iterator
,支持解引用,自增,自减,以及比较运算符,在容器内实现begin()
和end()
类方法,返回首个元素的iterator
以及末尾的iterator
。
Example Code:
1 |
|
Output:
1 |
|
改变元素/状态
self_type &resize(const int size)
重置当前vector
到给定的大小。
使用了在g++和MSVC等编译器在实现vector容器中引入的vector增长因子。在这个类的实现中,增长因子为
2
,即当vector
空间已满时,会重新分配大小为原vector
的2
倍大小的空间。这也是allocator
的基本实现。
- 如果给定的大小小于当前的
size()
,那么将会忽略给定大小之后的元素。- 如果给定的大小大于或等于当前的
size()
但是小于当前的capacity()
,则会在不重新申请新的空间下,将vector末尾的指针移到指定的大小处。- 如果给定的大小大于当前的
capacity()
,那么会重新申请并分配大小为当前capacity()
两倍的空间,并将原来的内容按顺序拷贝到新的空间中。
Example Code:
1 |
|
Output:
1 |
|
其他
self_type &push_front(element_right_reference argument)/self_type &push_front(const_element_reference argument)
self_type &push_back(element_right_reference argument)/self_type &push_back(const_element_reference argument)
self_type &pop_front()
self_type &pop_back()
element_type pop_back(element_reference out_param)
self_type &insert(const_iterator position, const_element_reference val)
self_type &insert(const_iterator position, size_type num, const_element_reference val)
self_type &insert(const_iterator position, InputIterator first, InputIterator last)
self_type &insert(const_iterator position, element_right_reference val)
self_type &insert(const_iterator position, std::initializer_list<element_type> object)
self_type &erase(const_iterator position)
self_type &erase(const_iterator first, const_iterator end)
self_type &clear()
self_type &reverse()
self_type slice(const_iterator begin, const_iterator end)
void swap(self_type &object)
self_type &operator=(const self_type &object)
self_type &operator=(self_type &&object)
self_type &operator=(const std::initializer_list<element_type> init_list)
Example Code:
1 |
|
Output:
1 |
|
更多的示例代码,可以参见
test.cpp
。
迭代器
实现方法与C++ STL的方法类似,用法基本相同,具体用法参见C++参考手册。
附录
类型重定义
Code, written in header:
1 |
|
有关使用ostream
进行输出vector
的运算符重载
此处借鉴了Python
对list
进行输出的格式。
Example Code: