一维数组封装类

    最近在看<Data Structure for Game Programmers>,还是有很多地方值得去学习。这里仿照其中的一维数组类,自己写了一遍,其中还可以增加很多功能,以后再去完善了。

 // ============================================================================

// 文件摘要:通用一维数组类
// 文件标识:Array1D.h
// 创建日期:2010-10-28
// ============================================================================
#ifndef ARRAR1D_H
#define ARRAR1D_H

#include 
<cstdio>
#include 
<iostream>

template 
<class ElemType>
class Array1D
{
public:
    
//构造函数,分配初始内存
    Array1D(int p_capacity = INIT_SIZE):elements(0),size(0),capacity(p_capacity)
    {
        
//采用new来分配内存
        elements = new ElemType[capacity];
    }

    
//析构函数,释放分配内存
    ~Array1D()
    {
        
if(elements != 0)
        {
            
//采用delete来配对new
            delete[] elements;
        }

        
//避免野指针(wild pointer或者stray pointer)
        elements = 0;
    }

    
//改变数组大小
    bool Resize(unsigned newCapacity);

    
//下标访问符号
    ElemType& operator[](int pIndex);

    
//转换操作符,作参数时会自动转换成指针
    operator ElemType *()
    {
        
return elements;
    }

    
//插入元素
    bool Insert(ElemType item,int pIndex);

    
//删除元素
    bool Delete(int pIndex,ElemType &delItem);

    
//获取容量大小
    size_t GetCapacity() const
    {
        
return capacity;
    } 

    
//获取实际大小
    size_t GetSize() const
    {
        
return size;
    }

    
//打印数组信息
    void ToString() const
    {
        std::cout 
<< "数组总容量为:" << capacity << ";数组实际大小为:" << size << endl;
        
for(size_t index =0; index < size; ++index)
        {
            
if(index % 10 == 0)
            {
                std::cout 
<< endl;
            }
            std::cout 
<< elements[index] << "\t";
        }
        std::cout 
<< endl;
    } 

    
//写数组元素到文件(可以考虑重载)
    bool WriteToFile(const char *path);

    
//读取文件到数组(可以考虑重载)
    bool ReadFromFile(const char *path);

    
//返回数组元素的前一个元素

    
//返回数组元素的后一个元素

private:
    
static const int INIT_SIZE = 100//首次分配大小 
    static const int INCR_SIZE = 10;  //重新分配增量
    ElemType *elements;               //数组元素首址
    size_t size;                      //数组实际大小
    size_t capacity;                  //数组容量大小
};

template 
<class ElemType>
inline 
bool Array1D<ElemType>::Resize(unsigned newCapacity)
{
    
bool result = false;
    
//申请新内存
    ElemType *newArray = new ElemType[newCapacity];

    
//申请失败
    if(newArray == 0)
        result 
= false;

    
//取小容量
    size_t min = newCapacity < capacity ? newCapacity:capacity;

    
for(size_t index =0 ; index < min ; ++index)
    {
        newArray[index] 
= elements[index];
    }

    
//保存新容量
    capacity = newCapacity;

    
//保存新大小
    size = newCapacity <= size ? newCapacity : size;

    
//删除老数组
    if(elements != 0)
    {
        delete[] elements;
    }

    
//保存新数组
    elements = newArray;

    
//返回结果
    result = true;

    
return result;
}

template 
<class ElemType>
inline ElemType
& Array1D<ElemType>::operator[](int pIndex)
{
    
return elements[pIndex];
}

template 
<class ElemType>
inline 
bool Array1D<ElemType>::Insert(ElemType item,int pIndex)
{
    
bool result = true;
    
//先检测大小是否足够,否则重新分配
    if(size >= capacity)
    {
        
//重新分配内存增量
        if(!Resize(capacity + INCR_SIZE))
        {
            result 
= false;
        }
    }
    
    
//右移
    for(int index = size - 1; index > pIndex ; --index)
    {
        elements[index 
+ 1= elements[index];
    }

    
//插入位置赋值
    elements[pIndex] = item;

    
//实际大小增一
    ++size;

    
return result;
}

template 
<class ElemType>
inline 
bool Array1D<ElemType>::Delete(int pIndex,ElemType &delItem)
{

    
//一种更快的删除元素的方法,只要移动一个元素(如果不关心元素的次序)
    
// bool result = true;
    
// -- size;
    
// delItem = elements[pIndex];
    
// elements[pIndex] = elements[size-1];
    
// return result;

    
bool result = true;

    
//保留删除值
    delItem = elements[pIndex];
    cout 
<< "删除了元素:" << delItem << endl;
    
//左移
    for(size_t index = pIndex + 1; index < size  ; ++index)
    {
        elements[index
-1= elements[index];
    }

    
//实际大小减一
    --size;

    
//返回
    return result;
}

template 
<class ElemType>
inline 
bool Array1D<ElemType>::WriteToFile(const char *path)
{
    std::FILE
* outfile = 0;
    
int written = 0;

    
//打开文件
    outfile = std::fopen(path,"wb");

    
//打开失败
    if( outfile == 0 )
        
return false;

    
//写数组
    written = std::fwrite(elements,sizeof(ElemType), size, outfile);
    std::fclose(outfile);

    
//如果写入的元素数目与实际不符,则有问题
    if( written != size )
        
return false;

    
//返回成功
    return true;
}

template 
<class ElemType>
inline 
bool Array1D<ElemType>::ReadFromFile(const char *path)
{
    std::FILE
* infile = 0;
    
int read = 0;

    
//打开文件
    infile = std::fopen(path, "rb");

    
//打开失败
    if( infile == 0 )
        
return false;

    
//读取文件,返回读取数目
    read = fread(elements, sizeof(ElemType),size,infile);
    std::fclose(infile);

    
//如果读入数目不符
    if( read != size )
        
return false;

    
//返回成功
    return true;
}
#endif

 

 

相关的测试代码如下:

 #include <iostream>

#include <tchar.h>
#include 
<string>
#include 
<cstdlib>
#include 
<cstring>
#include 
<ctime>
#include 
<sys/timeb.h>

#include 
"Array1D.h"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    
//新建一个int数组,初始总容量为50,实际大小为0
    Array1D<int> intArr(50);


    
string s1;

    
string *ptr = &s1;

    
//打印结果
    intArr.ToString();
    
    
//插入49个元素
    for(int i=0; i < 49++i)
    {
        intArr.Insert(rand()
%100,i);
    }

    
//打印结果
    intArr.ToString();

    
//再插入两个就达到初始容量51个了,此时会新增10个容量空间
    intArr.Insert(50,49);
    intArr.Insert(
51,50);

    
//再打印结果
    intArr.ToString();

    
int ret = 0;
    
//删除两个元素后
    intArr.Delete(1,ret);
    intArr.Delete(
50,ret);

    
//再打印结构
    intArr.ToString();

    
//改变数组大小
    intArr.Resize(200);

    
//打印结构
    intArr.ToString();

    
    system(
"pause");
    
return 0;
}

 

 

posted on 2010-10-29 16:10  虚怀若谷  阅读(1539)  评论(0编辑  收藏  举报

导航