自定义vector
今天上课老师讲了一下关于new运算符的用法,其中有一个是先申请内存,然后再用对象初始化内存的用法。当讲到这里的时候,老师用了一个自定义vector的例子作为示范。
网上有很多关于自定义vector的例子,但是大多没有解释为什么要先申请内存空间再初始化内存的原因。
现在解释一下原因:
首先我们要知道T* p = new T;这个代码的所做的事情。他做了三件事,
第一、初始化内存,
第二、将这个内存用T类型的对象进行初始化,
第三、返回改地址给p
在我们这个自定义vector中,如果T是内置数据类型,比如int等,完全可以直接new一块区域,然后再一个一个push_back即可,
但是,如果T代表的是一个类类型,则不可以,因为new完以后,会直接创建一个对象,所以如果new T的话则会创建
size个T对象,这不是我们想要的。所以介于这种情况,我们可以先申请一块size大小的内存空间,然后再将一个对象复制
进去,即实现了内存开辟与初始化分离的效果,也不会将所有空间都赋值为一个对象
不多讲了,上代码:
// MyVector.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include ‹iostream>
#include ‹string>
#include ‹cstddef>
#include ‹conio.h>
using namespace std;
template ‹typename T>
class MyVector
{
public:
MyVector():elements(0),first_free(0),end(0) {}
void push_back(const T& NewItem);
void show();
private:
static std::allocator‹T> alloc;//用来创建管理内存
void reallocate();//用于按原来容量的两倍分配内存
T* elements;
T* first_free;
T* end;
};
template ‹typename T>
std::allocator‹T> MyVector‹T>::alloc;
template ‹typename T>
void MyVector‹T>::push_back(const T& NewItem)
{
if( first_free == end )
reallocate();
alloc.construct(first_free,NewItem);
++first_free;
}
template ‹typename T>
void MyVector‹T>::reallocate()
{
std::ptrdiff_t size = first_free - elements;
std::ptrdiff_t NewCapacity = 2*max(size,1);//这个max返回1和size最大的值,旨在MyVector元素为0的时候则创建一个
T* NewElements = alloc.allocate(NewCapacity);//分配新的容量大小的空间
//uninitialized_copy(elements,end,NewElements);//将elements到end的元素复制到以NewElements开始的内存中
T* NewInit = NewElements;//NewInit用来指示新开辟的那段内存空间,来进行赋值
for( T* p = elements; p != first_free;/*empty*/ )//调用p所指向对象的析构函数
{
*NewInit = *p;
NewInit++;
alloc.destroy(p++);
}
if( elements )
alloc.deallocate(elements,end - elements); //销毁内存,以elements为起始位置,往后销毁end-elements个地址
elements = NewElements; //开始位置置为新内存卡的首地址
first_free = elements + size; //第一个空位置置为首地址加上原有元素个数后的地址
end = elements + NewCapacity; //最后的指针指向首地址加上总共容量后的地址
}
template ‹typename T>
void MyVector‹T>::show()
{
for( T* p = first_free; p != elements; )
cout‹‹(*(--p))‹‹ ""‹‹endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
MyVector‹int> test1;
test1.push_back(0);
test1.push_back(1);
test1.push_back(2);
test1.show();
getchar();
return 0;
}
文档来源:51CTO技术博客https://blog.51cto.com/u_6220803/3198724
页:
[1]