竹杖芒_

动态数组Vector类模板的实现

Vector类模板的实现

1. C++中原始数组的重要特性:

  • 数组就是指向一块内存块的指针变量,数组的具体大小必须由程序员单独确定。
  • 内存块可以通过new[ ]分配,但此后必须通过delete释放。
  • 内存块不能重新调整大小(但可获得一个新的、更大的内存块,并用原来的内存块初始化,然后释放原内存块)

2.考虑类模板Vector的主要细节

  • 实现五大函数以提供拷贝构造函数和operator=的深层拷贝功能,并将提供一个析构函数以回收数组。此外,还将实现C++11的移动功能。
  • Vector将提供改变Vector的大小(一般是更大)的resize方法和reserve方法,后者将改变Vector的容量。这个容量通过为原始数组获取新的内存块、把老内存块复制到新内存块并回收老内存块而得以更新。
  • 提供operator[ ]的实现,其一般通过访问函数和修改函数的形式实现。
  • 提供诸如size、empty、clear、back、pop_back和push_back等基本方法。如果大小和容量相同,则push_back方法将调用reserve函数。
  • 对于内嵌类型iterator和const_iterator,Vector也将提供支持,并提供相关联的begin方法和end方法。
#include<algorithm>
template<typename Object>
class Vector {
private:
int theSize; //大小
int theCapacity; //容量
Object* objects; //原始数组
public:
static const int SPARE_CAPACITY = 16; //定义剩余空闲的缓冲容量
explicit Vector(int initSize = 0) :theSize{ initSize }, theCapacity{ initSize + SPARE_CAPACITY }//指定数组大小
{
objects = new Object[theCapacity];
}
//拷贝构造函数
Vector(const Vector& rhs) :theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ nullptr }
{
objects = new Object[theCapacity];
for (int k = 0; k < theSize; ++k) {
objects[k] = rhs.objects[k];
}
}
//移动构造函数
Vector(Vector&& rhs) :theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ rhs.objects }{
rhs.objects = nullptr;
rhs.theSize = 0;
rhs.theCapacity = 0;
}
Vector& operator=(const Vector& rhs) {
Vector copy = rhs;
std::swap(*this, copy);
return *this;
}
Vector& operator=(Vector&& rhs) {
std::swap(theSize, rhs.theSize);
std::swap(theCapacity, rhs.theCapacity);
std::swap(objects, rhs.objects);
return *this;
}
~Vector() {
delete[]objects;
}
void resize(int newSize) //change the current size
{
if (newSize > theCapacity)
reserve(newSize * 2);
theSize = newSize;
}
void reserve(int newCapacity) { //reset the capacity
if (newCapacity < theSize)
return;
Object* newArray = new Object[newCapacity];
for (int k = 0; k < theSize; ++k)
newArray[k] = std::move(objects[k]);
theCapacity = newCapacity;
std::swap(objects, newArray);
delete[]newArray;
}
Object& operator[](int index) {
return objects[index];
}
const Object& operator[](int index)const {
return objects[index];
}
bool empty()const {
return size() == 0;
}
int size()const {
return theSize;
}
int capacity()const {
return theCapacity;
}
void push_back(const Object& x) {
if (theSize == theCapacity)
reserve(theCapacity*2+1);
objects[theSize++] = x;
}
void push_back(Object&& x) {
if (theSize == theCapacity)
reserve(theCapacity * 2);
objects[theSize++] = std::move(x);
}
void pop_back() {
--theSize;
}
const Object& back()const {
return objects[theSize - 1];
}
typedef Object* iterator; //指针变量的别名
typedef const Object* const_iterator;
iterator begin() {
return &objects[0];
}
const_iterator begin() const{
return &objects[0];
}
iterator end() {
return &objects[size()];
}
const_iterator end()const {
return &objects[size()];
}
};
posted @   aw11  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示