Array、StaticArray、DynamicArray

本文详细介绍了Array类的特点及其两种实现方式:StaticArray和DynamicArray。StaticArray通过模板参数固定数组大小,实现拷贝构造和赋值操作,可能产生数据截断;DynamicArray则动态调整数组大小,完全复制目标数组,避免数据截断,但在调整大小时可能舍弃多余数据。

Array类的特点

  Array类的特点:
    -数组类包含数组长度信息,能够发现参数是否越界(扔异常)
    -重载[],使得可以像原生数组一样使用
    -定义为抽象父类,使用指针完成数组的基本功能
    -指针指向的存储空间的大小与位置由子类提供

数组类的继承结构

Array的实现

Array.h

#ifndef _Array_H_
#define _Array_H_
#include "include/CPlusPlus.h"
#include "include/Object.h"
#include "include/Exception.h"

namespace JYlib
{

template < typename T >
class Array:public Object
{
protected:
	T* m_array;
public:
	virtual bool set(int i,const T& e)
	{
		bool ret = (0 <= i)&&(i < length());
		
		if(ret)
		{
			m_array[i] = e;
		}

		return ret;
	}

	virtual bool get(int i,T& e)const
	{
		bool ret = (0 <= i)&&(i < length());
		
		if(ret)
		{
			e = m_array[i];
		}
		return ret;
	}

	T& operator [](int i)
	{
		if((0 <= i)&&(i < length()))
		{
			return m_array[i];
		}
		else
		{
			THROW_EXCEPTION(IndexOutOfBoundsException,"Parameter i is invalid ...");
		}
	}

	T operator [](int i)const
	{
		return (const_cast<Array<T>&>(this))[i];
	}

	T* array()const
	{
		return m_array;
	}

	virtual int length()const =0;
};

}


#endif

StaticArray的实现

  StaticArray的特点:
    -使用模板参数决定数组大小
    -实现了拷贝构造与赋值操作
    -拷贝原数组与目标数组中空间大小较小的数据,可能会产生截断(多余数据舍弃)

StaticArray.h

#ifndef _StaticArray_H_
#define _StaticArray_H_
#include "Array.h"


namespace JYlib
{

template < typename T,int N >
class StaticArray:public Array<T>
{
protected:
	T m_space[N];
public:
	StaticArray()
	{
		this->m_array = m_space;
	}

	StaticArray(const StaticArray<T,N>& obj)
	{
		this->m_array = m_space;

		int length = (N < obj.length() ? N : obj.length);

		for(int i=0;i<length;i++)
		{
			m_space[i]=obj.m_space[i];
		}
	}

	StaticArray<T,N>& operator =(const StaticArray<T,N>& obj)
	{
		if(this != &obj)
		{
			int length = (N < obj.length() ? N : obj.length);
			for(int i=0;i<length;i++)
			{
				m_space[i]=obj.m_space[i];
			}
		}
		return *this;
	}

	int length()const
	{
		return N;
	}
};

}


#endif

DynamicArray的实现

  DynamicArray的特点:
    -动态决定数组的大小
    -实现了拷贝构造与赋值操作
    -拷贝出一个与目标数组一模一样的数组(空间大小与数据),不会发生截断
    -动态重置数组大小时,可能产生截断(多余数据舍弃)

DynamicArray.h

#ifndef _DynamicArray_H_
#define _DynamicArray_H_
#include "include/Array.h"
#include "include/Exception.h"

namespace JYlib
{

template < typename T >
class DynamicArray:public Array<T>
{
protected:
	int m_capacity;//动态内存大小

	//被复制数组,复制长度,新数组大小 返回新数组首地址
	T* copy(T* obj_array,int capacity,int new_capacity)
	{
		T* new_array = new T[new_capacity];

		if(new_array != NULL)
		{
			int length = (new_capacity < capacity ? new_capacity : capacity);

			for(int i = 0;i < length;i++)
			{
				new_array[i] = obj_array[i];
			}
		}
		return new_array;
	}

	//对象新地址,对象新空间大小	(更新对象信息,会释放原对象,符合异常安全性)
	void update(T* obj_array,int capacity)
	{
		if(obj_array != NULL)
		{
			T* temp = this->m_array;
			m_capacity = capacity;
			this->m_array = obj_array;

			delete[] temp;
		}
		else
		{
			THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create DynamicList object ...");
		}
	}

	//对象地址,对象空间大小	(初始化对象信息,不会delete)
	void init(T* obj_array,int capacity)
	{
		if(obj_array != NULL)
		{
			this->m_array = obj_array;
			m_capacity = capacity;
		}
		else
		{
			THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create DynamicList object ...");
		}
	}
public:
	DynamicArray(int capacity = 1)
	{
		init(new T[capacity],capacity);
	}

	DynamicArray(const DynamicArray<T>& obj)
	{
		init(copy(obj.m_array,obj.m_capacity,obj.m_capacity),obj.m_capacity);
	}

	DynamicArray<T>& operator =(const DynamicArray<T>& obj)
	{
		if(this != &obj)
		{
			update(copy(obj.m_array,obj.m_capacity,obj.m_capacity),obj.m_capacity);//复制出一个一模一样的数组

			/*//复制对象内容,原空间大小不变(可能会产生截断)
			int length = (m_capacity < obj.length() ? m_capacity : obj.length());
			for(int i=0;i<length;i++)
			{
				this->m_array[i]=obj.m_array[i];
			}
			*/
		}
		return *this;
	}

	void resize(int new_capacity)
	{
		if(new_capacity != m_capacity)
		{
			update(copy(this->m_array,this->m_capacity,new_capacity),new_capacity);
		}
	}

	int length()const
	{
		return m_capacity;
	}

	~DynamicArray()
	{
		delete[] (this->m_array);
	}
};

}


#endif

### 在 VBA 中声明初始化数组 在 VBA 中,数组可以通过静态声明或动态声明来定义。以下是关于如何声明初始化数组的详细说明: #### 静态数组 静态数组是在声明时就指定了大小的数组。一旦声明了大小,就不能再更改。 ```vba Dim StaticArray(5) As Integer ' 声明一个包含 6 个元素(索引从 0 到 5)的整数数组。 ``` 如果希望数组的索引从 1 开始而不是默认的 0,可以在模块的顶部使用 `Option Base 1` 语句[^1]。 ```vba Option Base 1 Dim StaticArray(5) As Integer ' 索引范围为 1 到 5。 ``` #### 动态数组 动态数组是在运行时才确定大小的数组。这需要先声明数组变量,然后使用 `ReDim` 语句来分配内存空间。 ```vba Dim DynamicArray() As Integer ' 声明一个动态数组。 ReDim DynamicArray(10) ' 分配 11 个元素的空间(索引从 0 到 10)。 ``` 动态数组的优点在于可以根据程序运行时的需求调整其大小。如果需要保留现有数据并增加数组大小,可以使用 `ReDim Preserve` 语句[^1]。 ```vba ReDim Preserve DynamicArray(20) ' 扩展数组到 21 个元素,并保留原有数据。 ``` #### 初始化数组 数组可以通过循环或其他方法进行初始化。例如,使用 `For` 循环为每个元素赋值: ```vba Dim i As Integer For i = LBound(DynamicArray) To UBound(DynamicArray) DynamicArray(i) = i * 2 ' 将每个元素设置为其索引值的两倍。 Next i ``` 或者直接通过代码块赋值(适用于小型数组): ```vba Dim ArrayExample(2) As String ArrayExample(0) = "Apple" ArrayExample(1) = "Banana" ArrayExample(2) = "Cherry" ``` #### 使用 `Split` 函数初始化数组 如果需要将字符串拆分为数组,可以使用 `VBA.Split` 函数[^2]。 ```vba Dim items As Variant items = VBA.Split("第1段-第2段-第3段", "-") ' 按 "-" 分隔字符串。 For Each Item In items Debug.Print Item ' 输出每个分隔后的字符串。 Next Item ``` #### 清空数组 使用 `Erase` 语句可以清空数组的内容。对于静态数组,它会将所有元素重置为默认值;对于动态数组,它会释放所占用的内存[^3]。 ```vba Dim StaticArray(5) As Integer Erase StaticArray ' 将每个元素设为 0。 Dim DynamicArray() As Integer ReDim DynamicArray(10) Erase DynamicArray ' 释放数组所用内存。 ``` ### 注意事项 - 静态数组的大小在声明时固定,无法更改。 - 动态数组需要使用 `ReDim` 来分配或重新分配大小。 - 使用 `Erase` 时需要注意数组类型,避免误操作导致程序异常。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值