C語言面向物件之STL庫--Vector
阿新 • • 發佈:2019-01-27
標頭檔案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); }