DXUT11框架浅析(8)--CGrowableArray

DXUT11中的CGrowableArray模板类提供类似于std::vector的功能,用于顺序存储数据。文章详细介绍了该类的定义、主要成员方法如SetSizeInternal、Add和Insert的实现,以及使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




DXUT11框架浅析(8)--CGrowableArray

 

 

 

         CGrowableArray是一个模板类,实现了类似std::vector的数据结构。是一个基本数组,数据按顺序的依次存放。

 

 

1. 类的定义

 

template<typename TYPE> class CGrowableArray
{
public:
	// 构造和销毁一个数组
	CGrowableArray()  { m_pData= NULL; m_nSize= 0; m_nMaxSize = 0; }
	CGrowableArray(const CGrowableArray<TYPE>& a) { for( int i=0; i < a.m_nSize; i++ ) Add( a.m_pData[i] ); }
	CGrowableArray& operator = ( constCGrowableArray<TYPE>&a )
	{ if( this == &a ) return *this; RemoveAll(); for( int i=0; i < a.m_nSize; i++ ) Add( a.m_pData[i] ); return *this; }
	~CGrowableArray(){ RemoveAll(); }
 
	// 为数组增加元素
	HRESULT Add( const TYPE& value);
	HRESULT Insert( int nIndex, const TYPE& value);
	HRESULT SetAt( int nIndex, const TYPE& value);
 
	// 元素的个数
	HRESULT SetSize( intnNewMaxSize );
	int     GetSize()const { return m_nSize; }
 
	// 读取元素的值
	const TYPE& operator[](int nIndex )const { return GetAt( nIndex); }
	TYPE&   operator[]( intnIndex ) { returnGetAt( nIndex); }
	TYPE&   GetAt( int nIndex ) const { assert( nIndex >= 0 && nIndex< m_nSize ); returnm_pData[nIndex];}
	TYPE*   GetData(){ return m_pData;}
 
	// 搜索元素
	int     IndexOf(const TYPE&value ) { return( m_nSize > 0 ) ? IndexOf( value, 0, m_nSize ) : -1; }
	int     IndexOf(const TYPE&value, int iStart ) { return IndexOf( value,iStart, m_nSize- iStart ); }
	int     IndexOf(const TYPE&value, int nIndex, int nNumElements );
 
	int     LastIndexOf(const TYPE&value ) { return( m_nSize > 0 ) ? LastIndexOf( value, m_nSize-1, m_nSize) : -1; }
	int     LastIndexOf(const TYPE&value, int nIndex ) { return LastIndexOf( value,nIndex, nIndex+1); }
	int     LastIndexOf( constTYPE& value,int nIndex, int nNumElements);
	bool    Contains(const TYPE&value ){ return( -1 != IndexOf( value) ); }
 
	// 清理元素或数组
	HRESULT Remove( int nIndex );
	void    RemoveAll(){ SetSize(0); }
	void    Reset() { m_nSize = 0; }
 
protected:


	// 指向存放实际数据的数组
	TYPE* m_pData;



	
	// 数组的元素个数
	int m_nSize;
	int m_nMaxSize;     // max allocated
 
	HRESULTSetSizeInternal( int nNewMaxSize );  // This versiondoesn't call ctor or dtor.
};


 

2. 主要成员方法

 

SetSizeInternal()检查缓冲区大小是否满足需要,如果不够用,则重建新的缓冲区

根据指定的数组成员个数nNewMaxSize,检查是否要重新分配内存。当然这个nNewMaxSize要求不能超过整形的最大值INT_MAX。

nNewMaxSize * sizeof( TYPE )便是所需分配的缓冲区内存大小(以字节为单位)。

如果需要重新分配内存,那么指向数组的m_pData指针和数组最多能存放元素个数的m_nMaxSize对象都要更新。

 

 

Add()在数组尾部添加一个新的元素

template<typename TYPE> HRESULT CGrowableArray <TYPE>::Add( const TYPE& value )
{
	HRESULT hr;

// 检查缓冲区
	if( FAILED( hr = SetSizeInternal( m_nSize + 1 ) ) )
		return hr;

	assert( m_pData != NULL );

// 创建一个新的TYPE*对象
	::new ( &m_pData[m_nSize] ) TYPE;

// 将值赋给这个新建的对象,增加元素个数
	m_pData[m_nSize] = value;
	++m_nSize;

	return S_OK;
}


 

 

Insert()在数组中间插入一个新的元素

template<typename TYPE> HRESULT CGrowableArray <TYPE>::Insert( int nIndex, const TYPE& value )
{
	HRESULT hr;

	// 检查传入的nIndex是否超出范围
	if( nIndex < 0 ||
		nIndex > m_nSize )
	{
		assert( false );
		return E_INVALIDARG;
	}

	// 检查缓冲区
	if( FAILED( hr = SetSizeInternal( m_nSize + 1 ) ) )
		return hr;

	// 移动内存
	MoveMemory( &m_pData[nIndex + 1], &m_pData[nIndex], sizeof( TYPE ) * ( m_nSize - nIndex ) );

	// 创建一个新的TYPE*对象
	::new ( &m_pData[nIndex] ) TYPE;

	//将值赋给这个新建的对象,增加元素个数
	m_pData[nIndex] = value;
	++m_nSize;

	return S_OK;
}

IndexOf()

template<typename TYPE> int CGrowableArray <TYPE>::IndexOf( const TYPE& value, int iStart, int nNumElements )
{
	// 检查传入的iStart和nNumElements是否有效
	if( iStart < 0 ||
		iStart >= m_nSize ||
		nNumElements < 0 ||
		iStart + nNumElements > m_nSize )
	{
		assert( false );
		return -1;
	}

	// 遍历数组各个元素,查找满足value值的成员,如果找到,则记录index
	for( int i = iStart; i < ( iStart + nNumElements ); i++ )
	{
		if( value == m_pData[i] )
			return i;
	}

	// Not found
	return -1;
}

 

 

3. 使用示例

 

CGrowableArray<int> m_TestList;
m_TestList.Add(3);
m_TestList.Add(5);
m_TestList.Add(7);
m_TestList.Add(9);
int nSize = m_TestList.GetSize();
int nIndex7 = m_TestList.IndexOf(7);
if( nIndex7 != -1 )
{
	m_TestList.Remove(nIndex7);
}





 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值