1. 程式人生 > >C語言面向物件之STL庫--Vector

C語言面向物件之STL庫--Vector

標頭檔案cssVector.h

/*
 * cssVector.h
 *
 *  Created on: 2017年10月18日
 *      Author: JasonHuo
 */

#ifndef SECURITY_CSSVECTOR_H_
#define SECURITY_CSSVECTOR_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "cssObject.h"

//////////////////////////
//   stl容器類方法返回值   //
//////////////////////////
#define VEC_RET_SUCCESS 1   ///返回成功
#define VEC_RET_FAILD 0     ///返回失敗


/******************************************************************************
@bref STL容器類,因為我們的偉大的C語言中沒有寫出我們常用的動態容器,為了更好的使用記憶體,我在這裡
參照C++版本的vector建立的 cssVector類。該容器類可以存放任何型別的個的引數。只要在初始類的時候
告訴類你需要存放的類的記憶體大小就可以了,可以使用sizeof()函式獲取型別大小便可。尤為強大的是,
cssVector會記憶體自增長。不過尤為遺憾的是,我這裡只實現了幾個我常用到的方法,如果你想獲取更強大
的功能可以繼承我這個類來建立更加強大的vector。

該類是採用css巨集定義類架構編寫,繼承與基類。建立該類後在生命週期結束時需要手動呼叫基類的個
Release方法
-------------------------------------------------------------------------------
@param
--------
int mSize                       容器中元素的個數
int mMaxSize                    該容器最大儲存元素的個數
int mTypeSize                   該容器儲存元素的型別,記憶體大小
int _mUsedMemLen                該容器已經使用的記憶體長度
int _mMemLen                    該容器擁有的記憶體長度
void *_mHead                    該容器的元素頭指標
void *_mEnd                     該容器的元素尾指標
-------------------------------------------------------------------------------
@fun
--------
checkPicketLine                 警戒線檢測函式
vecIsFull                       判斷容器是否已經滿
vecRresize                      容器自身記憶體擴大兩倍函式
vecPush_back                    向容器的尾部新增一個元素
vecPop_back                     從容器的尾部刪除一個元素
vecAt                           訪問容器 index 位置的個元素。可讀寫
vecClear                        將容器原本所有記憶體清楚,從新讓容器獲取只能存放一個元素的記憶體
vecModifyAt                     修改容器 index 位置的元素內容
*******************************************************************************/
#define cssVectorFields(TYPE) \
      cssObjectFields(TYPE) \
      int mSize; \
      int mMaxSize; \
      int mTypeSize; \
      int _mUsedMemLen; \
      int _mMemLen; \
      void *_mHead; \
      void *_mEnd;\
      void(*onCssObjectDelloc)(TYPE _this); \
      int (*vecIsFull)(TYPE _this); \
      int (*vecRresize)(TYPE _this); \
      int (*vecPush_back)(TYPE _this,void *pValue); \
      int (*vecPop_back)(TYPE _this); \
      void* (*vecAt)(TYPE _this,int index); \
      int (*vecClear)(TYPE _this); \
      int (*vecModifyAt)(TYPE _this,int index,void *pValue);

cssClass(cssVector)

/**
 * cssVector容器初始化函式,這裡會配置cssVector的所有方法,同時分配類記憶體
 * @param  _this    容器自身指標,this
 * @param  typeSize 容器存放型別的記憶體大小,相當於 C++ vector<int>;
 *                   這裡typeSize = sizeof(int)
 * @param  elemNum  初始化可以存放元素的個數
 * @return          返回容器類指標
 */
cssVector *cssVectorInit(cssVector *_this,int typeSize,int elemNum);

/**
 * 建立容器類
 * @param  typeSize 容器存放型別的大小
 * @param  elemNum  容器個初始存放個數
 * @return          返回容器指標
 *
 * @exp
 * -----------------------------------------------
 * C++中程式碼
 * vector<int> vecInt;
 *            ...
 * vector<int>().swap(vecInt);
 * -----------------------------------------------
 * css 程式碼
 * cssVector *pVecInt =cssVectorCreat(sizeof(int),1);
 *            ....
 * pVecInt->Release();
 * -----------------------------------------------
 * 然後後續使用類似
 */
cssVector *cssVectorCreat(int typeSize,int elemNum);


#ifdef __cplusplus
}
#endif

#endif /* SECURITY_CSSVECTOR_H_ */

原始檔檔案cssVector.c

/*
 * cssVector.c
 *
 *  Created on: 2017年10月18日
 *      Author: JasonHuo
 */
#include "cssVector.h"

//記憶體清理函式
static void cssVectorOnDelloc(cssVector * _this)
{
	free(_this->_mHead);
	_this->onCssObjectDelloc(_this);
}

static int vecIsFull(cssVector *_this)
{
	return _this->_mUsedMemLen==_this->_mMemLen?1:0;
}

static int vecResize(cssVector *_this)
{
	int ret = VEC_RET_FAILD;
	//獲取兩倍的記憶體
	int newMemLen = _this->_mMemLen<<1;
	void *mempty =malloc(newMemLen);
	if(mempty!=NULL)
	{
		//將原本記憶體中的資料拷貝到到新的記憶體當中
		//並且釋放原來的記憶體
		memset(mempty,0,newMemLen);
		memcpy(mempty,_this->_mHead,_this->_mUsedMemLen);
		free(_this->_mHead);
		_this->_mEnd = _this->_mHead+_this->_mUsedMemLen;
		_this->_mMemLen = newMemLen;
		_this->mMaxSize <<=1;
		ret = VEC_RET_SUCCESS;
	}
	return ret;
}

static int vecPush_back(cssVector *_this,void *pValue)
{
	if(_this->vecIsFull(_this)==1)
	{
		//如果記憶體已經滿了,則將原來的記憶體擴大兩倍
		_this->vecRresize(_this);
	}

	//將新來的資料拷貝到個容器當中
	memcpy(_this->_mEnd,pValue,_this->mTypeSize);
	_this->_mEnd +=_this->mTypeSize;
	_this->mSize++;
	_this->_mUsedMemLen+=_this->mTypeSize;
	return VEC_RET_SUCCESS;
}

static int vecPop_back(cssVector *_this)
{
	int ret = VEC_RET_FAILD;
	if(_this->mSize!=0)
	{
		_this->_mEnd-=_this->mTypeSize;
		_this->_mUsedMemLen-=_this->mTypeSize;
		_this->mSize--;
		ret = VEC_RET_SUCCESS;
	}
	return ret;
}

static void *vecAt(cssVector *_this,int index)
{
	void *atPtr = NULL;
	if(index<_this->mSize && index >=0)
	{
		atPtr = _this->_mHead+_this->mTypeSize*index;
	}
	return atPtr;
}

static int vecClear(cssVector *_this)
{
	_this->_mUsedMemLen = 0;
	_this->_mMemLen = _this->mTypeSize;
	_this->mMaxSize = 1;
	_this->mSize = 0;
	free(_this->_mHead);
	_this->_mHead =malloc(_this->mTypeSize);
	memset(_this->_mHead,0,_this->mTypeSize);
	_this->_mEnd = _this->_mHead;
	return VEC_RET_SUCCESS;
}

static int vecModifyAt(cssVector *_this,int index,void *pValue)
{
	void *atPtr = _this->vecAt(_this,index);
	memcpy(atPtr,pValue,_this->mTypeSize);
	return VEC_RET_SUCCESS;
}

cssVector *cssVectorInit(cssVector *_this,int typeSize,int elemNum)
{
	cssObjectInit(cssAs(cssObject*,_this));

	//配置記憶體清除方法
	_this->onCssObjectDelloc = _this->onDelloc;
	_this->onDelloc = &cssVectorOnDelloc;

	if(elemNum>=0)
	{
		//分配容器記憶體
		void* memptr = malloc(typeSize*elemNum);
		memset(memptr,0,typeSize*elemNum);
		if(memptr == NULL)
			return _this;

		_this->mSize = 0;
		_this->mMaxSize = elemNum;
		_this->mTypeSize = typeSize;
		_this->_mUsedMemLen = 0;
		_this->_mMemLen = typeSize*elemNum;
		_this->_mHead = memptr;
		_this->_mEnd = memptr;


		//配置回撥函式
		_this->vecIsFull = &vecIsFull;
		_this->vecRresize = &vecResize;
		_this->vecPush_back = &vecPush_back;
		_this->vecPop_back = &vecPop_back;
		_this->vecAt = &vecAt;
		_this->vecClear = &vecClear;
		_this->vecModifyAt = &vecModifyAt;
	}
	return _this;
}

cssVector *cssVectorCreat(int typeSize,int elemNum)
{
	return cssVectorInit(cssAlloc(cssVector),typeSize,elemNum);
}