本文需要说明的是一种动态数组模板类(Array),可用于自定义的需要连续空间的容器,能有效得利用分配的空间,提供较高效的数组对象操作,和使用引用计数减少内存复制拷贝,内存头含有描述块,记录有效数据对象数量和总的内存对象大小。
特点如下:
(1)Array与std::vector或std::array不同。Array存储连续的对象,并且在对象内存前开辟一份数组描述块对数组进行描述。
(2)Array存储的数据数量是动态的,可以通过setLength调整,同时可以使用+、+=运算符向数组中追加数据。
(3)多个数组实例允许使用同一份数据内容,并且不会重复创建内容,这是该数组类最重要的特性以及主要涉及目的,即当从一个Array对象构造一个新的Array对象或者将他赋值给其他Array时不会产生新的内存申请和拷贝。多个Array的数据指向相同的内存区,并且通过引用计数管理该共同的内存区。
(4)当所有指向该内存区的Array对象都被销毁后,该内存会被释放。
(5)对一个空的Array追加内容时,他会自动开辟新的内存区用于存储新数据。
(6)对已经包含内容的Array追加或改写(通过[]下标运算)时,如果数组包含的内区还被其他数组引用,则会自动解除对原有内存区的引用并创建新的内存区存储新的数据。
使用注意:频繁的对数据进行追加操作是十分低效的,在已经确定要追加数量的情况下先调用setLength或者setCapacity设置最终长度或容量再进行追加将提高性能。
使用注意:Array设计只用于提供数据存取,因此数组中存放的内容不会被调用构造函数和析构函数。
具体的代码实现如下:
template <typename T>
class Array
{
public:
typedef T TYPE;
struct ArrayDesc //内存描述模块
{
volatile int refer;//引用计数
volatile unsigned int capacity;//内存数量大小
volatile unsigned int length;//目前对象数量大小
};
protected:
T* m_ptr;
public:
Array()
{
m_ptr = NULL;
}
Array(const Array<T> &another)
{
m_ptr = NULL;
operator = (another);
}
Array(const T* ptr, size_t length)
{
m_ptr = NULL;
setLength(length);
memcpy(m_ptr, ptr, length * sizeof(*ptr));
}
Array(size_t length)
{
m_ptr = NULL;
setLength(length);
}
~Array()
{
setLength(0);
}
//操作符=函数只是复制指针和增加引用计数(这里是减少了内存拷贝的,但在引用计数大于1时,为不影响其他引用对象,会使用内存拷贝)
inline Array<T>& operator =(const Array<T> &another)
{
if (m_ptr != another.m_ptr)//检查不是同一个对象
{
setLength(0);
//释放本对象的内存
if (another.m_ptr)
{
ArrayDesc *pDesc = ((ArrayDesc*) anothe