_Array类,类似于Vector,其实就是_string

例子:

using namespace lf;
using namespace std;int main() {_Array<int> a(10, -1);_Array<_string> s = { _t("one"), _t("two") };_pcn(a);_pcn(s);}

结果:

源代码_Array.h:

/*******************************************************************************************
文件名						: _Array.h作者							: 李锋功能							: 线性表创建时间						: 2016年07月16日最后一次修改时间				:  2024年09月15日
********************************************************************************************/
#ifndef __ARRAY_H_  
#define __ARRAY_H_#include "_StrW.h"
#include "_StrA.h"
#include "_Convert.h"
#include "_Object.h"_LF_BEGIN_/**********************************************************************************************************
1
vector与list区别
vector为存储的对象分配一块连续的地址空间,因此对vector中的元素随机访问效率很高。在vecotor中插入或者
删除某个元素,需要将现有元素进行复制,移动。如果vector中存储的对象很大,或者构造函数复杂,则在对现
有元素进行拷贝时开销较大,因为拷贝对象要调用拷贝构造函数。对于简单的小对象,vector的效率优于list。
vector在每次扩张容量的时候,将容量扩展2倍,这样对于小对象来说,效率是很高的。list中的对象是离散存储的,
随机访问某个元素需要遍历list。在list中插入元素,尤其是在首尾插入元素,效率很高,只需要改变元素的指针。综上所述:
vector适用:对象数量变化少,简单对象,随机访问元素频繁
list适用:对象数量变化大,对象复杂,插入和删除频繁
最大的区别是, list是双向的,而vector是单向的。
因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面
的原则:
1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。vector表示一段连续的内存区域,每个元素被顺序存储在这段内存中,对vector   的随机访问效率很高,但对非末尾元素的插入和删除则效率非常低。deque也表示一段连续的内存区域,但与vector不同的是它支持高效地在其首部插入和删除元素,它通过两级数组结构来实现,一级表示实际的容器,第二级指向容器的首和尾list表示非连续的内存区域并通过一对指向首尾元素的指针双向链接起来,插入删除效率高,随机访问效率低2stl提供了三个最基本的容器:vector, list, deque。vector和built - in数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此
它能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间
进行插入和删除会造成内存块的拷贝,另外,当该数组后的内存空间不够时,需要重新
申请一块足够大的内存并进行内存的拷贝。这些都大大影响了vector的效率。list就是数据结构中的双向链表(根据sgi   stl源代码),因此它的内存空间可以是不连续
的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它
没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除
和插入。deque是一个double - ended   queue,它的具体实现不太清楚,但知道它具有以下两个
特点:它支持[]操作符,也就是支持随即存取,并且和vector的效率相差无几,它支持在两端
的操作:push_back, push_front, pop_back, pop_front等,并且在两端操作上与list的效率
也差不多。因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面
的原则:
1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。**********************************************************************************************************线性表的定义:一个线性表是n(n>=0)个具有相同属性的数据元素的有限序列。其中各元系有着依次相邻的逻辑关系。线性表中数据元素个数n称为线性表的长度。n=0时该线性表称为空表。**************************************************************************************************************/
//#define _ARRAY_DEBUG_/// <summary>
/// 
/// </summary>
/// <typeparam name="T"></typeparam>
template<class T>
class _ArrayIterator
{
private:T* _Ptr;
public:/// <summary>/// 构造函数,传值迭代器管理的值/// </summary>/// <param name="pNode"></param>inline _ArrayIterator(T* pt) { _Ptr = pt; }/// <summary>/// 比较实现/// </summary>/// <param name="that"></param>/// <returns></returns>bool operator != (const _ArrayIterator& that) { return _Ptr != that._Ptr; }/// <summary>/// 自增实现/// </summary>/// <returns></returns>inline _ArrayIterator& operator ++ () { ++_Ptr;   return *this; }/// <summary>/// 解引用,取值/// </summary>/// <typeparam name="T"></typeparam>T& operator * () { return *_Ptr; }};//_Array相当于std::vector,不限于线性表。
template<typename T>
class _Array : public _Object
{
public:
/*using traits_type    = _Traits;using allocator_type = _Alloc;using value_type      = _Elem;using size_type       = typename _Alty_traits::size_type;using difference_type = typename _Alty_traits::difference_type;using pointer         = typename _Alty_traits::pointer;using const_pointer   = typename _Alty_traits::const_pointer;using reference       = value_type&;using const_reference = const value_type&;using iterator       = _String_iterator<_Scary_val>;using const_iterator = _String_const_iterator<_Scary_val>;using reverse_iterator       = _STD reverse_iterator<iterator>;using const_reverse_iterator = _STD reverse_iterator<const_iterator>;
*/using iterator		=	_ArrayIterator<T>;using value_type	=	T;protected:T*			_pData;						//指针,指向第一个元素size_t		_nElementCount;				//无素个数size_t		_nBufferCount;				//缓冲元素个数size_t		_nDefaultBufferCount = 8;	//缺省缓冲数量size_t		_nAutoBufferCount = 0;		//自动设置缓冲次数的计数器public:static const int npos = -1;//-----------------------------------------------------------------------------------------------------------构造与析构函数
public: /// <summary>/// vector<int> ivec(10,-1);  //10个int元素,每个都初始化为-1/// </summary>/// <param name="nElementCount">元素数量</param>/// <param name="tDefaultValue">默认值</param>/// 创建时间:????-??-??    最后一次修改时间:2024-09-15 inline explicit _Array(const size_t& nElementCount = 0, const T& tDefaultValue = T()){/*构造函数中不能调用虚函数指的是直接或者隐式使用 this指针调用虚函数由于,不能确定this指针所代表的对象,包括其中指向虚函数表的指针,有没有构造完成,即包括指向虚函数表的指针在内的所有成员有没有,完全构造完成,所以难以正常使用虚函数。更重要的就是一些指针,还没有构造的时候,就用到了--这是野指针--,结果不确定!!!比如有一个 char指针,起到类似 string 的作用,只是需要动态分配内存,没有分配内存时,就是个野指针,一旦 使用的虚函数,使用了这个指针,后果就很严重。更严重的问题是,基类对子类的虚函数,如何使用完全没有谱,因为子类还没有定义。而且没有任何标志,表示虚函数表指针构造完成。虚函数没法调用。有标志也不行,子类会更改,虚函数表指针;虚函数表指针,会随着父类->子类;逐层构造,逐渐更改。PS:关于2.构造函数中调用结果运行行为正常,即已具有正常多态行为(因为在进入构造函数函数体之前,构造对象的虚函数表,对象中虚函数表指针,对象成员都已初始化完成,已是完整的派生类对象)。这个说法有问题,父类正在构造时候,子类对象,并没有开始构造,父类对象构造完成后,才会开始子类的构造,这时才会把虚函数表的指针,改成子类的虚函数表指针,这是单继承。多继承更复杂。*/#ifdef _ARRAY_DEBUG__cout << _t("inline explicit _Array(const size_t& nElementCount, const T& tDefaultValue = T())\n");#endifInitData(nElementCount,0,tDefaultValue,true,false);  //子类的InitData虚函数还未构造}/// <summary>/// 拷贝nCount个T数据到数组,默认还有8个T数据缓冲被初始化为零。/// </summary>/// <param name="pType">数据类型指针</param>/// <param name="nCount">数据个数</param>/// <param name="nDefaultBuffer">默认缓冲个数</param>/// <param name="bZeroBuffer">是否初始化缓冲为0</param>/// 创建时间:????-??-??    最后一次修改时间:2024-09-05 inline explicit _Array(const T* pType, const int nCount, const int nDefaultBuffer = 8, bool bZeroBuffer = true){
#ifdef _ARRAY_DEBUG__cout << _t("调用构造函数:_Array<T>::_Array(const T* pType, const int nCount, const int nDefaultBuffer = 8), 参数:") << _geti(nCount) << _geti(nDefaultBuffer) << _t("\n");
#endif_nDefaultBufferCount = nDefaultBuffer;InitData(0,nCount + _nDefaultBufferCount);Add(pType, nCount);if (bZeroBuffer)ZeroBufferAll();}inline _Array(const _Array& rhs){
#ifdef _ARRAY_DEBUG__cout << _t("调用构造函数: _Array<T>::_Array(const _Array& rhs)\n");
#endifif (&rhs == this || rhs._nElementCount == 0) {InitData(0);return;}_nDefaultBufferCount = rhs._nDefaultBufferCount;_nBufferCount = rhs._nBufferCount;_nElementCount = rhs._nElementCount;_pData = _Memory::New<T>(_nElementCount + _nBufferCount);_Memory::Copy(_pData, rhs._pData, _nElementCount);}/*C++11中新特性之:initializer_list详解C++11提供的新类型,定义在<initializer_list>头文件中。template< class T >class initializer_list;先说它的用处吧,然后再详细介绍一下。首先有了initializer_list之后,对于STL的container的初始化就方便多了,比如以前初始化一个vector需要这样:int a[] = {0, 1, 2, 3};std::vector<int> vec(a, a+sizeof(a));或者std::vector<int> vec;vec.push_back(1);vec.push_back(3);vec.push_back(3);vec.push_back(2);有了initializer_list后,就可以直接像初始化数组一样:复制代码class Test {private:static std::map<string, string> const nameToBirthday = {{"lisi", "18841011"},{"zhangsan", "18850123"},{"wangwu", "18870908"},{"zhaoliu", "18810316"},};}复制代码当然啦,里面的std::map必须提供参数为initializer_list的构造函数如:*/inline _Array(std::initializer_list<T> aList){InitData(0,aList.size() + _nDefaultBufferCount);Add(aList.begin(), aList.size());}/// <summary>/// /// </summary>/// <param name="v"></param>/// 创建时间:2024-07-01    最后一次修改时间:2024-07-01inline _Array(const std::vector<T>& v) {InitData(0,v.size() +_nDefaultBufferCount );for (const auto& tValue : v) {Add(tValue);}}/// <summary>/// /// </summary>/// <returns></returns>/// 创建时间:2023-05-03    最后一次修改时间:2023-05-03   inline _ArrayIterator<T> begin()const { return _ArrayIterator<T>(_pData); }/// <summary>/// /// </summary>/// <returns></returns>/// 创建时间:2023-05-03    最后一次修改时间:2023-05-03   inline _ArrayIterator<T> end()const{//迭代器使用的语句//for (_ArrayIterator<int> f = dl.begin(); f != dl.end(); f++) {       }return _ArrayIterator<T>(_pData + _nElementCount);}//-------------------------------------------------------------------------------------------------------------操作符重载
public:inline _Array<T>& operator=(const _Array<T>& rhs){if (&rhs != this){if ( &rhs != null && rhs._nElementCount != 0){_Memory::Delete<T>(_pData, _nElementCount + _nBufferCount);_nDefaultBufferCount = rhs._nDefaultBufferCount;_nBufferCount = rhs._nBufferCount;_nElementCount = rhs._nElementCount;_pData = _Memory::New<T>(_nElementCount + _nBufferCount);_Memory::Copy(_pData, rhs._pData, _nElementCount + _nBufferCount);}else{ClearMemory();}}return *this;}//重载的下标操作符inline T& operator[](const int& nIndex)const{
#ifdef _ARRAY_DEBUG_assert(nIndex < _nElementCount);
#endifreturn _pData[nIndex];}inline bool operator==(const _Array<T>& rhs) const{if (_pData == rhs._pData) return true;  //排除 相同引用  class aValue;    if( aValue == aValue)if (_pData == nullptr || rhs._pData == nullptr) return false;if (_nElementCount != rhs._nElementCount) return false;for (int n = 0; n < rhs._nElementCount; ++n){if (_pData[n] != rhs._pData[n]) return false;}return true;}inline bool operator!=(const _Array& rhs) const{return (*this == rhs ? false : true);}/*//模板类的友元函数,这里的的T跟T,是独立于类_Array<T>的template<typename T>friend bool operator== (const _Array<T>& lhs, const _Array<T>& rhs);template<typename T>friend bool operator!= (const _Array<T>& lhs, const _Array<T>& rhs);*/#if _CLR_/// <summary>/// /// </summary>/// <param name="arr"></param>/// 创建时间: 2022-12-25      最后一次修改时间:2022-12-25   inline _Array(cli::array<T>^ arr){InitData(0,arr->Length + 8);for each (T t in arr){Add(t);}}/// <summary>/// /// </summary>/// 创建时间: 2022-12-25      最后一次修改时间:2022-12-25  inline  operator cli::array<T>^ () const{cli::array<T>^ arr	= gcnew cli::array<T>(_nElementCount);for (int i = 0; i < _nElementCount; ++i){  arr[i] = _pData[i];}return arr;	 }#endifpublic://-----------------------------------------------------------------------------------------------------属性/// <summary>/// 内存大小,以 byte 为单位。/// </summary>/// <returns></returns>inline int GetMemoryLength()const { return sizeof(T) * (_nElementCount + _nBufferCount); }/// <summary>/// 字符串长度/// </summary>__declspec(property(get = GetMemoryLength)) const int MemoryLength;inline int GetDataMemoryLength()const { return sizeof(T) * _nElementCount; }/// <summary>/// 数据占用的内存长度,以 byte 为单位。/// </summary>__declspec(property(get = GetDataMemoryLength)) const int DataMemoryLength;/// <summary>/// vector 容器的容量(用 capacity 表示),指的是在不分配更多内存的情况下,/// 容器可以保存的最多元素个数;而 vector 容器的大小(用 size 表示),/// 指的是它实际所包含的元素个数。	对于一个 vector 对象来说,通过该模板类提供的 /// capacity() 成员函数,可以获得当前容器的容量;通过 size() 成员函数,可以获得容器当前的大小/// </summary>/// <returns></returns>inline int Capacity()const { return _nElementCount + _nBufferCount; }/// <summary>/// 每次重新分配内存缺省缓冲数量/// </summary>/// <returns></returns>inline int DefaultBuffer() const { return _nDefaultBufferCount; }/// <summary>/// 剩余缓冲数量/// </summary>/// <returns></returns>inline int Buffer() const { return _nBufferCount; }//设置缺省缓冲数量inline void DefaultBuffer(const int& nDefaultBuffer) { _nDefaultBufferCount = nDefaultBuffer; }//是否为空inline bool IsEmpty() { return _nElementCount == 0; }//----------------------------------------------------------------------------------------------------操作//查找元系的最大值inline const T* Min() const { return _Math::Min<T>(_pData, _nElementCount); }//查找元系的最小值inline const T* Max() const { return _Math::Max<T>(_pData, _nElementCount); }//开始位置inline  T* Begin()const { return _pData; }// 结束位置inline  T* End()const { return _pData + _nElementCount; }/// <summary>/// 返回一个翻转的数组/// </summary>/// <returns></returns>/// 创建时间:2023-05-01    最后一次修改时间:2023-05-01 inline _Array<T> Reverse()const{_Array<T> arrResult(_nElementCount);	for (int i = _nElementCount - 1; i >= 0; --i){arrResult.Add(_pData[i]);}return arrResult;}//---------------------------------------------------------------------------------------------------------虚拟函数,子类重写
protected:/// <summary>/// 初始化数据/// </summary>/// <param name="nElementCount">元素个数</param>/// <param name="nBufferCount">缓冲个数</param>/// <param name="tDefaultValue">元素默认值</param>/// <param name="bDefaultValue">是否设置元素默认值</param>/// <param name="bInitBuffer">是否初始化缓冲</param>/// 创建时间:????-??-??    最后一次修改时间:2024-09-15 inline virtual void InitData(const size_t& nElementCount = 0,const size_t& nBufferCount = 0,const T& tDefaultValue = T(),const bool& bDefaultValue= false,const bool& bInitBuffer = false){ _nBufferCount = nBufferCount;_nElementCount = nElementCount;_pData = null;if (_nElementCount + _nBufferCount > 0) {//分配内存_pData = _Memory::New<T>(_nElementCount + _nBufferCount);//初始化数据if (bDefaultValue) {for (size_t n = 0; n < _nElementCount; ++n) {*(_pData + n) = tDefaultValue;}}//初始化缓冲if (bInitBuffer) {for (size_t n = _nElementCount; n < _nElementCount + _nBufferCount; ++n) {*(_pData + n) = T();}}}		#ifdef _ARRAY_DEBUG__cout << _t("inline virtual void _Array<T>::InitData") << _t("\n");
#endif}public:/// <summary>/// _Array<_char> *ps = new LString("abc");  delete ps; /// 如果_Array的析构函数不用virtual,则上属语句LString的虚拟函数不会被调用/// 虚析构函数的作用是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。/// 当然,并不是要把所有类的析构函数都写成虚函数。因为当类里面有虚函数的时候,编译器/// 会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一/// 个类被用来作为基类的时候,才把析构函数写成虚函数。/// </summary>inline virtual ~_Array(){
#ifdef _ARRAY_DEBUG__cout << _t("_Array<T>::~_Array()\n");
#endifClearMemory();}/// <summary>/// 添加一串元素,pData为数据指针,nLength数据长度/// </summary>/// <param name="pData"></param>/// <param name="nLength"></param>/// <returns></returns>inline virtual _Array<T>& Add(const T* pData, const int& nLength){#ifdef _ARRAY_DEBUG_//_cout << _t("调用函数:inline virtual const T* add(const T* pData, const int nLength)\t参数:") << _geti(nLength) << _t("\n");;
#endif	 /*#ifdef  _STR_DEBUG__cout << _t("_Str<T>:\t inline  const _Str<T>& Add(const T& aChar) 参数:") << _geti(aChar) << _t("\n");
#endif //要判断 *pData == 0 防止  str_.Add(L"\0",1); if (aChar == 0) { return *this; }if (_nBufferCount >= 1){_pData[_nElementCount] = aChar;_nBufferCount -= 1;_nElementCount += 1;_pData[_nElementCount] = 0;}else{SetBuffer(1 + _nDefaultBufferCount * _Math::Pow(2, _nAutoBufferCount)); //自动设置缓冲次数加 if (_nBufferCount >= 1){_pData[_nElementCount] = aChar;_nBufferCount -= 1;_nElementCount += 1;_pData[_nElementCount] = 0;}else{throw _t("设置缓冲区失败!");}++_nAutoBufferCount;}return *this;}*/if (pData == null || nLength <= 0) return *this;if (_nBufferCount >= nLength){_Memory::Copy<T>(_pData + _nElementCount, pData, nLength);_nBufferCount -= nLength;_nElementCount += nLength;}else{	SetBuffer(nLength + _nDefaultBufferCount * _Math::pow(2, _nAutoBufferCount)); //自动设置缓冲次数加 if (_nBufferCount >= nLength){_Memory::Copy<T>(_pData + _nElementCount, pData, nLength);				 _nBufferCount -= nLength;_nElementCount += nLength;				 }else{throw _t("设置缓冲区失败!");}++_nAutoBufferCount;}return *this;}/// <summary>/// 添加单个元素/// </summary>/// <param name="rData"></param>/// <returns></returns>inline _Array<T>& Add(const T& rData){	return Add(&rData, 1);	}/// <summary>/// 添加一个数组/// </summary>/// <param name="arr"></param>/// <returns></returns>inline _Array<T>& Add(const _Array<T>& arr){return Add(arr.DataConst, arr.Length);}//删除元系,nStartPos为开始位置,nLength长度inline virtual const T* Del(const int& nStartPos, const int& nLength){if (nStartPos + nLength > _nElementCount){_nBufferCount = _nBufferCount + _nElementCount - nStartPos;_nElementCount = nStartPos + 1;}else if (nStartPos + nLength >= _nElementCount){_nElementCount -= nLength;_nBufferCount += nLength;}else{for (int n = nStartPos + nLength; n < _nElementCount; ++n){_pData[n - nLength] = _pData[n];}_nElementCount -= nLength;_nBufferCount += nLength;}return _pData;}/// <summary>/// 清空所有内存,并把指针设为null/// </summary>inline virtual void ClearMemory() override{#ifdef _ARRAY_DEBUG_//_cout << _t("void _Array<T>::ClearData()\n");#endifif (_nElementCount + _nBufferCount > 0 && _pData != null) {_Memory::Delete<T>(_pData, _nElementCount + _nBufferCount);}else {if (_pData != null) {throw "_pData != null";}}_pData = null;_nBufferCount = 0;_nElementCount = 0;}/// <summary>/// 清空数据,但不释放内存,只是把数据计数器重设为0。/// </summary>inline virtual void ClearData()override{_nBufferCount = _nBufferCount + _nElementCount;_nElementCount = 0;}/// <summary>///  设置缓冲数,如果原来缓冲区数量大于新设置的数量,则不设置。/// </summary>/// <param name="nBufferCount"></param>/// <param name="bZeroBuffer"></param>/// 创建时间:????-??-??    最后一次修改时间:2023-03-11 inline virtual void SetBuffer(const int& nBufferCount, const bool& bZeroBuffer = false){#ifdef _ARRAY_DEBUG__cout << _t("调用函数:inline virtual void SetBuffer(const int& nBufferCount)\t参数:") << _geti(nBufferCount) <<_t("\n");
#endif	 if (_nBufferCount >= nBufferCount) return;if (nBufferCount == 0) return;T* pNew = _Memory::New<T>(_nElementCount + nBufferCount);if (_nElementCount > 0)_Memory::Copy(pNew, _pData, _nElementCount);_Memory::Delete<T>(_pData, _nElementCount + _nBufferCount);_pData = pNew;_nBufferCount = nBufferCount;if (bZeroBuffer)ZeroBufferAll();}/// <summary>/// 转为String表示/// </summary>/// <returns></returns>/// 创建时间:2023-04-29    最后一次修改时间:2024-08-17inline virtual _string ToSplitString(const _string& sSplitString)  const override{  				_string sResult;_string sp = sSplitString.Length == 0 ? _string(_t(",")) : sSplitString;sResult.Add(_t("{"));if (_nElementCount > 0){for (int i = 0; i < _nElementCount - 1; ++i){sResult.std_append(_Convert::to_string_t<T>(_pData[i]));sResult.std_append(sp);}sResult.std_append(_Convert::to_string_t<T>(_pData[_nElementCount - 1]));}sResult.Add(_t("}"));return sResult;}inline _string ToString()const{return ToSplitString("");}/// <summary>/// 强制转换为String/// </summary>/// 创建时间:2023-04-29    最后一次修改时间:2023-04-29operator _stdstr()const{return ToString().std_c_str();}public: //从nStart开始向后查找aTypeValue第一次出现在当前容器中的位置,失败时返回_Array::nposinline int find(const T& aTypeValue, const int nStart = 0) const { return _Math::find(_pData, _nElementCount, &aTypeValue, 1, nStart); }//从nStart开始向后查找长度为pFindLength的pFind数据第一次出现在当前容器中的位置,失败时返回_Array::nposinline int find(const T* pFind, const int& nStart, const int& pFindLength) const { return _Math::find(_pData, _nElementCount, pFind, pFindLength, nStart); }//从nStart开始向后查找aFindLLinearList第一次出现在当前容器中的位置,失败时返回_Array::npos int find(const _Array& aFindLLinearList, const int& nStart = 0) const { return _Math::find(_pData, _nElementCount, aFindLLinearList._pData, aFindLLinearList._nElementCount, nStart); }//从nStart开始向前查找aTypeValue第一次出现在当前容器中的位置,失败时返回_Array::npos。inline int rfind(const T& aTypeValue, const int& nStart = npos) const { return _Math::rfind(_pData, _nElementCount, &aTypeValue, 1, nStart); }//从nStart开始向前查找长度为pFindLength的pFind数据第一次出现在当前容器中的位置,失败时返回_Array::nposinline int rfind(const T* pFind, const int& nStart, const int& pFindLength) const { return _Math::rfind(_pData, _nElementCount, pFind, pFindLength, nStart); }//从nStart开始向前查找aFindLLinearList第一次出现在当前容器中位置,失败时返回_Array::npos inline int rfind(const _Array& aFindLLinearList, const int& nStart = npos) const { return _Math::rfind(_pData, _nElementCount, aFindLLinearList._pData, aFindLLinearList._nElementCount, nStart); }//从nStart开始向后查找aTypeValue第一次出现的位置,失败时返回_Array::nposinline int find_First_of(const T& aTypeValue, const int& nStart = 0) const { return _Math::find_First_of(_pData, _nElementCount, &aTypeValue, 1, nStart); }//从nStart开始向后查找长度为pFindLength的pFind数据任一元素第一次出现的位置,失败时返回_Array::nposinline int find_First_of(const T* pFind, const int& nStart, const int& pFindLength) const { return _Math::find_first_of(_pData, _nElementCount, pFind, pFindLength, nStart); }//从nStart开始向后查找aFindLLinearList任一元素第一次出现的位置,失败时返回_Array::npos inline int find_First_of(const _Array& aFindLLinearList, const int& nStart = 0) const { return _Math::find_first_of(_pData, _nElementCount, aFindLLinearList._pData, aFindLLinearList._nElementCount, nStart); }//从nStart开始向后查找aTypeValue第一次不出现的位置,失败时返回_Array::nposinline int find_First_not_of(const T& aTypeValue, const int& nStart = 0) const { return _Math::find_first_not_of(_pData, _nElementCount, &aTypeValue, 1, nStart); }//从nStart开始向后查找长度为pFindLength的pFind数据任一元素第一次不出现的位置,失败时返回_Array::nposinline int find_First_not_of(const T* pFind, const int& nStart, const int& pFindLength) const { return _Math::find_first_not_of(_pData, _nElementCount, pFind, pFindLength, nStart); }//从nStart开始向后查找aFindLLinearList任一元素第一次不出现的位置,失败时返回_Array::npos inline int find_First_not_of(const _Array& aFindLLinearList, const int& nStart = 0) const { return _Math::find_first_not_of(_pData, _nElementCount, aFindLLinearList._pData, aFindLLinearList._nElementCount, nStart); }//从nStart开始向前查找aTypeValue第一次出现的位置,成功返回索引处,失败时返回_Array::nposinline int find_last_of(const T& aTypeValue, const int& nStart = 0) const { return _Math::find_last_of(_pData, _nElementCount, &aTypeValue, 1, nStart); }//从nStart开始向前查找pFind中元系第一次出现的位置,成功返回索引处,失败时返回_Array::nposinline int find_last_of(const T* pFind, const int& nStart, const int& pFindLength) const { return _Math::find_last_of(_pData, _nElementCount, pFind, pFindLength, nStart); }//从nStart开始向前(倒序)查找aFindLLinearList任一元素第一次出现的位置,找到返回索引处,失败时返回_Array::nposinline int find_last_of(const _Array& aFindLLinearList, const int& nStart = 0) const { return _Math::find_last_of(_pData, _nElementCount, aFindLLinearList._pData, aFindLLinearList._nElementCount, nStart); }//从nStart开始向前查找aTypeValue第一次不出现的位置,失败时返回_Array::nposinline int find_last_not_of(const T& aTypeValue, const int& nStart = 0) const { return _Math::find_last_not_of(_pData, _nElementCount, &aTypeValue, 1, nStart); }//从nStart开始向前查找长度为pFindLength的pFind数据任一元素第一次不出现的位置,失败时返回_Array::nposinline int find_last_not_of(const T* pFind, const int& nStart, const int& pFindLength) const { return _Math::find_last_not_of(_pData, _nElementCount, pFind, pFindLength, nStart); }//从nStart开始向前查找aFindLLinearList任一元素第一次不出现的位置,失败时返回_Array::npos inline int find_last_not_of(const _Array& aFindLLinearList, const int& nStart = 0) const { return _Math::find_last_not_of(_pData, _nElementCount, aFindLLinearList._pData, aFindLLinearList._nElementCount, nStart); }public:/// <summary>/// 临时整型数据,方法函数调用。/// </summary>int TmepEffectiveCount = 0;/// <summary>/// 把有效长度后一位数据进行初始化,如果是数字,则会自动初始化0。/// </summary>inline void ZeroBufferOne() {if (this->_nBufferCount > 0)this->_pData[this->_nElementCount] = T();}/// <summary>/// 初始化剩下的缓冲区/// </summary>inline void ZeroBufferAll() {if (this->_nBufferCount > 0){for (int i = 0; i < _nBufferCount; ++i){_pData[i + _nElementCount] = T();}}}/// <summary>/// 重新设置元素的长度,这个长度不能超过 OldLength + Buffer/// </summary>/// <param name="nNewLength"></param>/// 创建时间:????-??-??    最后一次修改时间:????-??-??(2024/04/21)inline void ResetLength(const int& nNewLength) {if (nNewLength > this->Capacity()) {_char  sError[] = _t("新设置的长度已超过容器的最大长度!\n");_cout << _t("_Mem::ResetLength") << sError;throw sError;}int iCap = this->Capacity();this->_nBufferCount = iCap - nNewLength;this->_nElementCount = nNewLength;}/// <summary>/// 除非内存给其它对象托管,否则不要调用这个函数。/// 放置对象当前使用的内存,可能内存已托管给别的对象,/// 重新初始化当前对象/// </summary>/// 创建时间:2022-12-29    最后一次修改时间:2022-12-29inline virtual void GiveUpMem(){this->InitData(0);}/// <summary>/// 返回有nCount个元素的数组。/// </summary>/// <param name="nCount"></param>/// <returns></returns>/// 创建时间:2023-12-10    最后一次修改时间:2023-12-10   已测试static inline _Array<T> newElement(const size_t& nCount){_Array<T> tmp(nCount); //设置nCount个缓冲//把缓冲变成元素tmp._nBufferCount = 0; tmp._nElementCount = nCount;return tmp;  //此处C++编译器直接返回tmp对象,不会再构造一个_Array<T>.}public://----------------------------------------------------------------属性  inline T* GetData() { return this->_pData; }__declspec(property(get = GetData)) T* Data;inline const T* GetDataConst() const { return  this->_pData; }__declspec(property(get = GetDataConst)) const T* DataConst;/// <summary>/// 数组长度,无素个数/// </summary>__declspec(property(get = GetLength)) int Length;/// <summary>/// 有效元素的个数/// </summary>/// <returns></returns>inline int GetLength()const { return _nElementCount; }/// <summary>/// 自动分配内存次数/// </summary>/// 创建时间:2024-08-18    最后一次修改时间:2024-08-18__declspec(property(get = GetAutoBufferCount)) size_t AutoBufferCount;inline const size_t& GetAutoBufferCount()const{ return _nAutoBufferCount; }}; //-------------------------------------------------------------------------------------_Array#ifdef _UNICODE_template<class T>
std::wistream& operator >> (std::wistream& os, _Array<T>& arr)
{_cout << _t("std::wistream& operator >> (std::wistream& os, _Array<T>& aString){未完成!\n");return os;
}template<class T>
std::wostream& operator<<(std::wostream& os, const _Array<T>& arr)
{os << arr.ToString();return os;
}#else
template<class T>
std::istream& operator >> (std::istream& os, _Array<T>& aString)
{_cout << _t("std::wistream& operator >> (std::wistream& os, _Array<T>& aString){未完成!\n");return os;
}template<class T>
std::ostream& operator<<(std::ostream& os, const _Array<T>& arr)
{os << arr.ToString();return os;
}#endif_LF_END_ //------------------------------------------------------------------------------_LF_END_ #endif // !_ARRAY_H_

_ByteArray.h

/*******************************************************************************************
文件名						: _ByteArray.h作者							: 李锋功能							: 字节数组创建时间						: 2022年01月01日最后一次修改时间				:  2022年01月05日
********************************************************************************************/#ifndef __BYTEARRAY_H_
#define __BYTEARRAY_H_#include "_Array.h"
#include "_StrA.h"
#include "_StrW.h"_LF_BEGIN_/// <summary>
/// _Byte 数组
/// </summary>
class _ByteArray final : public _Array<_byte>
{
public:explicit _ByteArray(int nBuffer = 0) : _Array<_byte>(nBuffer) {}explicit _ByteArray(const _ByteArray& ba, const size_t&  nCount);
public:void TrusteeshipMem(const _byte* pData, const int nDataMemoryLength, const int& nMemoryLength);void TrusteeshipMem(_string& sText);void TrusteeshipMem(_ByteArray& ba);//int AddString(const _string& S);int AddStringA(const _StrA& s);int AddStringW(const _StrW& s);int AddFloat(const float& fValue);int AddInt(const int& iValue);int AddInt64(const __int64& iValue);int AddByte(const _byte& bValue);//_string  ReadString(const int& nPos, const int& nLength);_StrA  ReadStringA(const int& nPos, const int& nLength);_StrW  ReadStringW(const int& nPos, const int& nLength);bool ReadFromFile(const _char* sFileName);bool WriteToFile(const _char* sFileName);/// <summary>/// 类型转换,转换成T类型/// </summary>/// <typeparam name="T"></typeparam>/// <param name="nStart">指针开始位置</param>/// <returns>返回T类型的引用</returns>/// 创建时间:2024-08-12    最后一次修改时间:2024-08-12template<class T> const T& ToAny(const size_t& nStart = 0)const{lassert( _nElementCount >= nStart + sizeof(T)   ,"转换的数据太大了,大于数组本身所分配的内存。");T* pt = (T*)_pData + nStart;return *pt;}/// <summary>/// 转换为宽字符串/// </summary>/// <returns></returns>/// 创建时间:2024-08-12    最后一次修改时间:2024-08-12const _string ToWString()const;
};_LF_END_  //------------------------------------------------------------------------------------------_LF_END_#endif  //------------------------------------------------------------------- #endif 

_ByteArray.cpp

#include "_ByteArray.h"
#include "global_c_all.h"_LF_BEGIN__ByteArray::_ByteArray(const _ByteArray& ba, const size_t& nCount)
{if (nCount >= ba.Length){Add(ba);}else{_Array<_byte>::Add(ba.DataConst, nCount);}
}/// <summary>
/// 释放本身内存,托管新的内存。
/// </summary>
/// <param name="pData"></param>
/// <param name="nDataMemoryLength">数据长度</param>
/// <param name="nMemoryLength">使用内存长度</param>
/// 创建时间:2023-01-04    最后一次修改时间:2023-01-05
void _ByteArray::TrusteeshipMem(const _byte* pData, const int nDataMemoryLength, const int& nMemoryLength)
{ClearMemory();  //清除内存_nBufferCount = nMemoryLength - nDataMemoryLength;if (_nBufferCount < 0){throw _t("托管内存错误!");}_pData = (_byte*)pData;_nElementCount = nDataMemoryLength;
}/// <summary>
/// 托管String对象,并放本身内存。
/// </summary>
/// <param name="sText"></param>
/// 创建时间:2023-01-04    最后一次修改时间:2023-01-05
void _ByteArray::TrusteeshipMem(_string& sText)
{TrusteeshipMem((const _byte*)sText.Data, sText.DataMemoryLength, sText.MemoryLength);sText.GiveUpMem();
}/// <summary>
/// 释放本身内存,托管其它对象
/// </summary>
/// <param name="ba"></param>
/// 创建时间:2023-01-04    最后一次修改时间:2023-01-05
void _ByteArray::TrusteeshipMem(_ByteArray& ba)
{TrusteeshipMem((const _byte*)ba.Data, ba.GetDataMemoryLength(), ba.GetMemoryLength());ba.GiveUpMem();
}/*
int  _ByteArray::AddString(const _string& s)
{if (s.Length == 0) return -1;int nPos = Length;Add((_byte*)s.Data, (int) (sizeof(_char) * s.Length) );return nPos;}
*/
int _ByteArray::AddStringA(const _StrA& s)
{if (s.Length == 0) return -1;int nPos = _nElementCount;Add((_byte*)s.Data, (int)(sizeof(char) * s.Length));return nPos;
}int _ByteArray::AddStringW(const _StrW& s)
{if (s.Length == 0) return -1;int nPos = _nElementCount;Add((_byte*)s.Data, (int)(sizeof(wchar_t) * s.Length));return nPos;
}int _ByteArray::AddFloat(const float& fValue)
{int nPos = _nElementCount;Add((_byte*)&fValue, sizeof(float));return nPos;
}int _ByteArray::AddInt(const int& iValue)
{int nPos = _nElementCount;Add((_byte*)&iValue, sizeof(int));return nPos;
}int _ByteArray::AddInt64(const __int64& iValue)
{int nPos = _nElementCount;Add((_byte*)&iValue, sizeof(__int64));return nPos;
}int _ByteArray::AddByte(const _byte& bValue)
{int nPos = _nElementCount;Add(&bValue, sizeof(_byte));return nPos;
}/*
_string _ByteArray::ReadString(const int& nPos, const int& nLength)
{int n = nLength / sizeof(_char);return _string( (_char*) (_pData + nPos), n);
}
*/_StrA _ByteArray::ReadStringA(const int& nPos, const int& nLength)
{int n = nLength / sizeof(char);return _StrA((char*)(_pData + nPos), n);
}_StrW _ByteArray::ReadStringW(const int& nPos, const int& nLength)
{int n = nLength / sizeof(wchar_t);return _StrW((wchar_t*)(_pData + nPos), n);
}bool _ByteArray::ReadFromFile(const _char* sFileName)
{return ga.ReadFileToBuffer<_byte>(sFileName, *this);}bool _ByteArray::WriteToFile(const _char* sFileName)
{return ga.WriteFile<_byte>(sFileName, *this);
}const _string _ByteArray::ToWString() const
{	 return (wchar_t*)_pData;
}_LF_END_

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/424671.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FastText 和 Faiss 的初探了解

概览 大模型目前已经是如火如荼的程度&#xff0c;各个大厂都有推出面向大众的基础大模型&#xff0c;同时诸多行业也有在训练专有大模型&#xff0c;而大模型的发展由来却是经过多年从文本检索生成、深度学习、自然语言处理&#xff0c;在Transformer架构出来后&#xff0c;才…

python的流程控制语句之制作空气质量评估系统

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

什么是数据库回表,又该如何避免

目录 一. 回表的概念二. 回表的影响三. 解决方案1. 使用覆盖索引2. 合理选择索引列3. 避免选择不必要的列4. 分析和优化查询5. 定期更新统计信息6. 避免使用SELECT DISTINCT或GROUP BY7. 使用适当的数据库设计 数据库中的“回表”是指在查询操作中&#xff0c;当数据库需要访问…

【免费】CISSP官方习题集第4版

伴随2004年4月CISSP新大纲发布&#xff0c;CISSP官方习题集第4版(OPT v4)已于2024年5月出版&#xff1a; 本人维护的中英对照8个知识域分章节练习已同步更新完成&#xff0c;在保持v3版内容基础上&#xff0c;增补了所有v4新内容&#xff0c;免费供考友们使用&#xff0c;访问方…

离线数仓DWD层

离线数仓DWD层 DWD层设计要点&#xff1a;9.1 交易域加购事务事实表9.2 交易域下单事务事实表9.3 交易域取消订单事务事实表9.4 交易域支付成功事务事实表9.5 交易域退单事务事实表9.6 交易域退款成功事务事实表9.7 交易域购物车周期快照事实表9.8 工具域优惠券领取事务事实表9…

springboot修改组件扫描包位置

步骤很详细&#xff0c;直接上教程 问题分析 默认情况下组件扫描包范围为启动类所在包及其子包 解决方法 我们只需要在启动类上面加个注解配置扫描范围 效果演示 温馨提示 非必要不建议修改&#xff0c;按规范创建项目结构一般不会出现这个问题

uniapp 发布苹果IOS详细流程,包括苹果开发者公司账号申请、IOS证书、.p12证书文件等

记录一下uniapp发布苹果IOS的流程。 一、苹果开发者公司账号申请 1、邓白氏编码申请&#xff08;先申请公司邓白氏编码&#xff0c;这一步需要1-2周&#xff0c;没有这个编码苹果开发者没法申请&#xff0c;已有编码的跳过此步骤&#xff09;&#xff1a; 1&#xff09;联系苹…

什么是职场?职场的本质又是什么呢?

最近&#xff0c;经常看到很多职场相关的&#xff0c;比如职场必备技能、职场人际关系、职场晋升等等&#xff0c;这些都是职场的一些方面&#xff0c;但是却少有人来深入剖析什么是职场&#xff0c;职场的本质又是什么&#xff0c;今天我们就来一起来聊一聊&#xff0c;到底职…

【MySQL】MySQL索引与事务的透析——(超详解)

前言 &#x1f31f;&#x1f31f;本期讲解关于MySQL索引事务&#xff0c;希望能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;【MySQL】MySQL表的增删改查&#xff08;进阶篇&#xff09;——之查询操作&#xff08;超级详解&#xff09;-CSDN博客 &#x1f308;感…

【计算机网络 - 基础问题】每日 3 题(一)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

HTML贪吃蛇游戏

文章目录 贪吃蛇游戏 运行效果代码 贪吃蛇游戏 贪吃蛇是一款经典的休闲益智游戏。本文将通过HTML5和JavaScript详细解析如何实现一个简易版的贪吃蛇游戏。游戏的主要逻辑包括蛇的移动、碰撞检测、食物生成等功能。以下是游戏的完整代码及注释解析。&#xff08;纯属好玩&#…

【python】OpenCV—Mask RCNN for Object Detection and Instance Segmentation

文章目录 1、任务描述2、MASR RCNN 网络结构3、方法实现4、结果展示5、涉及到的库getPerfProfile 6、参考 1、任务描述 利用 mask rcnn 网络&#xff0c;进行图片和视频的目标检测和实例分割 2、MASR RCNN 网络结构 3、方法实现 # Copyright (C) 2018-2019, BigVision LLC (L…

SQL进阶技巧:火车票相邻座位预定一起可能情况查询算法 ?

目录 0 场景描述 1 数据准备 2 问题分析 2.1 分析函数法 2.2 自关联求解 3 小结 如果觉得本文对你有帮助&#xff0c;那么不妨也可以选择去看看我的数字化建设通关指南博客专栏 &#xff0c;或许对你更有用。专栏原价99&#xff0c;现在活动价29.9&#xff0c;按照阶梯…

什么是上拉,下拉?

上拉就是将引脚通过一个电阻连接到电源&#xff0c;作用&#xff1a;1.使IO口的不确定电平稳定在高点平&#xff0c;2、为了增加IO口拉电流的能力。 下拉就是将引脚通过一个电阻与GND相连&#xff0c;作用&#xff1a;1.从器件输出电流 2.当IO口为输入状态时&#xff0c;引脚的…

GitHub Star 数量前 13 的自托管项目清单

一个多月前&#xff0c;我们撰写并发布了这篇文章《终极自托管解决方案指南》。在那篇文章里我们深入探讨了云端服务与自托管方案的对比、自托管的潜在挑战、如何选择适合自托管解决方案&#xff0c;并深入介绍了五款涵盖不同场景的优秀自托管产品。 关于自托管的优势&#xf…

快速了解高并发解决方案

对《高并发的哲学原理》的个人总结&#xff0c;原书地址如下 https://pphc.lvwenhan.com/ 本书的核心思想就是拆分&#xff0c;服务细化拆分多资源并行。 通用设计方法 例子&#xff1a;每秒100万次http请求 通过架构解决性能问题&#xff0c;在面对并发需求时&#xff…

Tuxera NTFS for Mac 2023绿色版

​ 在数字化时代&#xff0c;数据的存储和传输变得至关重要。Mac用户经常需要在Windows NTFS格式的移动硬盘上进行读写操作&#xff0c;然而&#xff0c;由于MacOS系统默认不支持NTFS的写操作&#xff0c;这就需要我们寻找一款高效的读写软件。Tuxera NTFS for Mac 2023便是其中…

idea激活页面怎么打开

打开Help------选择Register 然后就可以选择激活方式了

Java 入门指南:JVM(Java虚拟机)——类的生命周期与加载过程

文章目录 类的生命周期类加载过程1&#xff09;载入&#xff08;Loading&#xff09;2&#xff09;验证&#xff08;Verification&#xff09;文件格式验证符号引用验证 3&#xff09;准备&#xff08;Preparation&#xff09;4&#xff09;解析&#xff08;Resolution&#xf…

【渗透测试】——DVWA靶场搭建

&#x1f4d6; 前言&#xff1a;DVWA&#xff08;Damn Vulnerable Web Application&#xff09;是一个用于安全漏洞测试的 PHP/MySQL 网络应用&#xff0c;旨在为安全专业人士提供一个合法的环境&#xff0c;以测试他们的技能和工具&#xff0c;同时帮助 Web 开发者更好地理解 …