自定义的列表主要是效率上稍微好些,不像stl那样的调用,有较多的封装。
特点:
1)功能跟stl::vector类似,封装更为简单,不使用迭代器模式,只是使用下标索引方式。
2)提供取内存指针访问方式
取出数据指针就可以使用了(类似stl vector的data函数),重载了操作符
inline operator T* () const { return m_pData; } ,这样可以直接直接取出使用 类似CBList< myclass > list;myclass * listdata = list; 然后就使用listdata 了。
3)可以使用addList接口来为该列表追加另一个列表,可一次性复制列表数据,减少多次函数调用和数据复制。
定义代码如下:
typedef long int INT_PTR;
template <typename T>
class CBList
{
public:
typedef CBList<T> ListClass;
protected:
T* m_pData;
INT_PTR m_tMaxCount;
INT_PTR m_tCount;
public:
CBList()//初始化时,内存为空
{
m_pData = 0;
m_tMaxCount = 0;
m_tCount = 0;
}
virtual ~CBList()
{
empty();//析构自动释放内存
}
inline INT_PTR count() const { return m_tCount; }//获取数据数量
inline INT_PTR maxCount() const { return m_tMaxCount; }//获取内存大小(对象内存大小为单位)
void insert(const INT_PTR index, const T& data)//插入数据到下标为index的位置(数据个数大于内存大小时则拓展内存大小到2倍)
{
assert( index > -1 && index <= m_tCount );
if ( m_tCount >= m_tMaxCount )
reserve( (m_tMaxCount > 0) ? m_tMaxCount * 2 : 16 );
if ( index < m_tCount )
{
memmove( &m_pData[index + 1], &m_pData[index], sizeof(T) * (m_tCount - index) );
}
m_pData[index] = data;
m_tCount++;
}
INT_PTR add(const T& data)//添加数据到列表(数据个数大于内存大小时则拓展内存大小到2倍)
{
if ( m_tCount >= m_tMaxCount )
reserve( (m_tMaxCount > 0) ? m_tMaxCount * 2 : 16 );
memcpy(&m_pData[m_tCount], &data, sizeof(data));
m_tCount++;
return m_tCount-1;
}
inline const T& get(const INT_PTR index) const //获取下标index下的数据
{
assert( index > -1 && index < m_tCount );
return m_pData[index];
}
inline void set(const INT_PTR index, const T &item)//设置下标index下的数据为item
{
assert( index > -1 && index < m_tCount );
m_pData[index] = item;
}
INT_PTR index(const T& data) const //获取data的下标
{
INT_PTR i;
for ( i=m_tCount-1; i>-1; --i )
{
if ( m_pData[i] == data )
{
return i;
}
}
return -1;
}
void remove(const INT_PTR index)//移除下标index下的数据
{
assert( index > -1 && index < m_tCount );
remove( index, 1 );
}
void remove(const INT_PTR index, const INT_PTR count)//移除下标index下标后的count个数据
{
assert( index + count <= m_tCount );
if ( count > 0 )
{
memcpy( &m_pData[index], &m_pData[index + count], sizeof(m_pData[0]) * (m_tCount - index - count) );
m_tCount -= count;
}
}
virtual void empty()//释放列表内存
{
clear();
m_tMaxCount = 0;
if (m_pData)
{
free( m_pData );
m_pData = 0;
}
}
inline void clear()//清除列表数据(不删除内存)
{
m_tCount = 0;
}
inline void trunc(const INT_PTR count) // 设置列表的数据个数(只能减少)
{
assert( count > -1 && count <= m_tMaxCount );
m_tCount = count;
}
virtual void reserve(INT_PTR count)//保留列表数据空间(若空间增加则重新分配空间,否则不做任何操作)
{
if ( count > m_tCount && count != m_tMaxCount )
{
m_tMaxCount = count;
m_pData = (T*)realloc( m_pData, sizeof(T) * count );
}
}
inline void addList(const CBList<T> &list)//添加新列表数据到列表末尾
{
addArray((T*)list, list.m_tCount);
}
inline void addArray(T* data, INT_PTR length)//添加数组到该列表末尾
{
if ( m_tCount + length > m_tMaxCount )
reserve(m_tCount + length);
memcpy(&m_pData[m_tCount], data, length * sizeof(T));
m_tCount += length;
}
inline INT_PTR push(const T& data)//压入元素
{
return add(data);
}
inline T pop()//弹出元素
{
if ( m_tCount > 0 )
{
m_tCount--;
return m_pData[m_tCount];
}
throw "stack was empty"; //弹出元素异常(数量不够)
}
inline operator T* () const { return m_pData; }//获取列表数据的指针
};