C++(7):vector源码②
⼀、vector源码
1.交换函数(引⽤不仅可以引⽤变量,还可以引⽤指针,则交换函数也可以交换指针)
template<class T>
void Swap(T &a, T &b)
{
T c = a;
a = b;
b = c;
}
2.构造函数
template <class _T> //⽆参的构造函数
inline void construct(_T* p)
{
new (p) _T();
}
template <class _T1, class _T2> //模板函数的重载,有参的构造函数
inline void construct(_T1*p, const _T2& value)
{
new (p) _T1(value);
}
3.析构函数
template <class _Tp>
inline void destroy(_Tp* pointer)
localmode
{
pointer->~_Tp(); //析构对象
}
template <class _FI>meetingminutes
inline void destroy(_FI first, _FI last)
{
for ( ; first != last; ++first)
{
destroy(&*first);
}
}
int main()
{
torrey devittoint n = 10;
Object* p = (Object*)malloc(sizeof(object) * n);
for (int i = 0; i, n; i++)
{
construct(&p[i], i + 10); //构造
}
destory(p, p + n); //析构
return 0;
}
⼆、向量基类
//向量基类有两个⽬的。⾸先,它的申请空间函数和释放空间函数分配(但不初始化)存储。quaker
//这使得异常安全更容易。
//其次,基类封装了SGI样式分配器和标准⼀致性分配器之间的所有差异
template <class _Tp>
class Vector_ba //向量基类/⽗类:申请和释放空间
{
public:
Vector_ba(): _M_start(0), _M_finish(0), _M_end_of_storage(0) {} //⽆参:列表形式初始化
Vector_ba(size_t n): _M_start(0), _M_finish(0), _M_end_of_storage(0) //有参
{
_M_start = _M_allocate(n); //构造空间
_M_finish = _M_start;
stefanie什么意思_M_end_of_storage = _M_start + n;
}
~Vector_ba()
{
_M_deallocate(_M_start, _M_end_of_storage - _M_start); //释放空间
}
protected:
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
_Tp* _M_allocate(size_t n)
{
return (_Tp*)malloc(sizeof(_Tp)*n);//
}
void _M_deallocate(_Tp* p, size_t n) //
{
free(p);
}
thule
};
template <class _Tp>
class vector : protected Vector_ba<_Tp> //先构造基类/⽗类
{ //再构造⾃⼰
private:
typedef Vector_ba<_Tp> _Ba;
public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type* iterator;
typedef const value_type* const_iterator; //能指向变量,但不能改变变量,但可以改变指向的变量
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef int difference_type;
public:
// 迭代器
iterator begin() { return _M_start; }
const_iterator begin() const { return _M_start; }
iterator end() { return _M_finish; }
const_iterator end() const { return _M_finish; }
/
/ 容量
size_type size() const
{
return size_type(end() - begin()); //指针和指针相减后时元素的个数
//return end()-begin();
}
size_type capacity() const //容量
{
return size_type(_M_end_of_storage - begin());
}
bool empty() const
{
台风英文
return begin() == end();
}
// 元素访问.reference⼀引⽤返回
//以下标形式访问,运算符重载
reference operator[](size_type n) { return *(begin() + n); }
const_reference operator[](size_type n) const { return *(begin() + n); }
//以at函数形式访问
reference at(const size_type pos)
{
if((size_type)(_M_finish - _M_start) <= pos)
{
_Xrange(); //抛出异常
}
return *(begin() + pos);
}
const_reference at(const size_type pos) const
{
if((size_type)(_M_finish - _M_start) <= pos)
{
_Xrange();
}
return *(begin() + pos);
}
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(end() - 1);//*--end() } //因为end指的是最后⼀个元素的后继位置,所以要-1 const_reference back() const { return *(end() - 1); }
// 数据访问:得到数据的⾸地址
pointer data() { return _M_start;}
const_pointer data() const { return _M_start;}
public:
// 构造/复制/销毁
explicit vector(): _Ba() {} //在⼦类中调⽤⽗类的构造函数
vector(size_type n, const _Tp& value) : _Ba(n) //先⽤⽗类构造n个空间
{
_M_finish = uninitialized_fill_n(_M_start, n, value);
}
explicit vector(size_type n) : _Ba(n)
{
_M_finish = uninitialized_fill_n(_M_start, n, _Tp());
}
vector(const vector<_Tp>& x): _Ba(x.size())
{
_M_finish = uninitialized_copy(x.begin(), x.end(), _M_start);
}
vector(const _Tp* first, const _Tp* last) : _Ba(last - first)
{
_M_finish = uninitialized_copy(first, last, _M_start);
}
~vector()
{
destroy(_M_start, _M_finish);
}
vector<_Tp>& operator=(const vector<_Tp>& x)
{
if (&x != this)
{
const size_type xlen = x.size();谢谢英文怎么写
if (xlen > capacity()) //x的元素个数⼤于this的空间
{
iterator tmp = M_allocate_and_copy(xlen, x.begin(), x.end());
destroy(_M_start, _M_finish); //析构对象
M_deallocate(_M_start, _M_end_of_storage - _M_start); //释放空间
_M_start = tmp;
_M_end_of_storage = _M_start + xlen; //最后空间容量变成了与xlen相等的值 }
el if (size() >= xlen) //⾃⼰的元素个数⼤于对⽅的元素个数
{
iterator i = copy(x.begin(), x.end(), begin());
destroy(i, _M_finish);
}
el //元素个数少,但容量⾜够容纳对⽅的元素个数
{
copy(x.begin(), x.begin() + size(), _M_start);
uninitialized_copy(x.begin() + size(), x.end(), _M_finish);
}
_M_finish = _M_start + xlen;
}
return *this;
}
void push_back(const _Tp& x) //尾插
{
if (_M_finish != _M_end_of_storage)
戴龙 罗伯斯{
construct(_M_finish, x);
++_M_finish;
}
el //容量不够来扩容
{
_M_inrt_aux(end(), x);
}
}
void pop_back()
{
--_M_finish;
finishing
destroy(_M_finish); //释放对象,空间并没有消失
}
iterator era(iterator position) //Pos位置的值删掉(删除末尾,会引起失效)
{
if (position + 1 != end()) //删掉的不是末尾
{
copy(position + 1, _M_finish, position); //从pos+1到末尾拷贝到pos中
}
--_M_finish; //末尾减1
destroy(_M_finish);
return position;
}
protected:
void _M_inrt_aux(iterator pos, const _Tp& x)
{
if (_M_finish != _M_end_of_storage)
{
construct(_M_finish, *(_M_finish - 1)); //把最后⼀个值放到最后⼀个值的后继位置
_Tp x_copy = x;
copy_backward(pos, _M_finish - 2, _M_finish - 1); //拷贝到pos位置停下来
*pos = x_copy;
}
el //容量等于个数,没有空间了
{
const size_type old_size = size();
//const size_type len = old_size != 0 ? 2 * old_size : 1;
const size_type len = old_size < 4? old_size+1:(old_size + old_size/2);
iterator new_start = _M_allocate(len);
iterator new_finish = new_start;
//__STL_TRY
{ //先扩容
new_finish = uninitialized_copy(_M_start, pos, new_start); //先考到pos
construct(new_finish, x); //新的数据插⼊
++new_finish;
new_finish = uninitialized_copy(pos, _M_finish, new_finish); //后⾯的数据拷下来
}
//__STL_UNWIND((destroy(new_start,new_finish), _M_deallocate(new_start,len))); //析构原来的对象
destroy(begin(), end());
_M_deallocate(_M_start, _M_end_of_storage - _M_start); //释放空间
_M_start = new_start;
_M_finish = new_finish;
_M_end_of_storage = new_start + len;
}
}