STL中的vector相当于动态数组的概念,其可以根据元素的多少而动态扩展。
本文实现一简易的类似vector的动态数组,以探究动态数组的实现原理。
#pragma once
template<class T>
class MyVector
{
public:
MyVector() : m_p(NULL), m_size(0), m_capacity(0) {}
~MyVector()
{
destroy_all();
free_memory();
}
MyVector(const MyVector& rhs) : m_p(NULL), m_size(0), m_capacity(0)
{
reserve(rhs.size());
m_size = rhs.size();
m_capacity = rhs.capacity();
for (int i = 0; i < m_size; ++i)
{
construct_at(i, rhs.at(i));
}
}
MyVector& operator=(const MyVector& rhs)
{
reserve(rhs.size());
destroy_all();
m_size = rhs.m_size;
for (int i = 0; i < m_size; ++i)
{
construct_at(i, rhs[i]);
}
return *this;
}
void reserve(size_t n)
{
if (n > m_capacity)
{
if (0 == m_capacity)
{
m_p = (T*)malloc(n * sizeof(T));
m_capacity = n;
}
else
{
T* temp = (T*)realloc(m_p, n * sizeof(T));
if (temp != m_p)
{
free_memory();
m_p = temp;
}
m_capacity = n;
}
}
}
inline size_t capacity() const
{
return m_capacity;
}
inline size_t size() const
{
return m_size;
}
inline bool is_empty() const
{
return m_size == 0;
}
void resize(size_t n, const T& t= T())
{
if (n > m_size)
{
reserve(n);
for (int i = m_size; i < n; ++i)
{
construct_at(i, t);
}
m_size = n;
}
else if (n < m_size)
{
for (int i = n; i < m_size; ++i)
{
destroy_at(i);
}
m_size = n;
}
}
void push_back(const T& t)
{
if (m_size == m_capacity)
{
reserve(m_capacity == 0 ? 1 : m_capacity * 2);
}
m_size++;
construct_at(m_size - 1, t);
}
void pop_back()
{
if (m_size > 0)
{
destroy_at(m_size - 1);
m_size--;
}
}
inline const T& at(size_t i) const
{
return m_p[i];
}
inline T& at(size_t i)
{
return m_p[i];
}
const T& operator[](size_t i) const
{
return m_p[i];
}
T& operator[](size_t i)
{
return m_p[i];
}
private:
inline void destroy_all()
{
for (int i = 0; i < m_size; ++i)
{
destroy_at(i);
}
}
inline void construct_at(size_t i, const T& t)
{
new(m_p + i) T(t);
}
inline void destroy_at(size_t i)
{
m_p[i].~T();
}
inline void free_memory()
{
if (NULL != m_p)
{
::free(m_p);
}
}
private:
T *m_p;
size_t m_size;
size_t m_capacity;
};