对象列表 - MetaTrader 5 库
/********************************************************************
对象列表
List 类模板提供了一个用于存储有序对象列表的基本容器。
为了方便起见,List 还提供了堆栈操作的同义词,
这使得使用 List 进行堆栈的代码更加明确,而无需定义另一个类。
/**/ /********************************************************************/ 模板<类型名>班级对象列表 {民众: //构造、销毁、初始化、赋值 对象列表(布尔值内存删除=真的):mdelete(memdelete) {} ObjectList(ObjectList&src) {mdelete=src.mdelete;复制(项目,src.items);复制(mem,src.mem);} 〜ObjectList(){删除全部();如果(mdelete) EmptyMem();} 对象列表 操作员=(对象列表&); 空白 内存删除(布尔值memdelete) {mdelete=memdelete;} //访问 时间* 操作员[](整数我) {返回获取(i);} T* 获取(整数在) {整数c=计数();如果(c>0&&在>=0&&在返回项目[在];}返回 无效的;} T* 首先() {整数c=计数();如果(c>0){返回项目[0];}返回 无效的;} T* 最后() {整数c=计数();如果(c>0){返回项目[c-1];}返回 无效的;} 布尔值 TryGet(T*dst,整数在) {如果((dst=获取(at))!=无效的){返回 真的;}别的{返回 错误的;}} // 整数 计数(){KillBad();返回 数组大小(项目);} 整数 查找(T*项目){整数c=计数();为了(整数我=0;我 如果(项目==项目[i]) {返回我;}}返回-1;} 空白 打印哈希(){为了(整数我=0;我<数组大小(项目);我++){打印格式(“%d:%d(%s)”,i,哈希(项目[i]),类型名(项目[i]));}} 整数 哈希(T*项目){细绳s;字符串连接(s,s,项目);返回(整数)字符串转整数(s);} 整数 哈希(整数at) {T*p=Get(at);返回(p!=无效的)?哈希(p):0;} //添加 空白 操作员+=(T*项目) {追加(项目);} 空白 操作员^=(T*item) {前置(item);} 空白 追加(T*项目){追加(项目,项目);} 空白 前置(T*项目){IncreaseAt(0);项目[0]=项目;} //删除 空白 操作员-=(T*item) {删除(item,0);} 空白 操作员/=(T*item) {删除(item,1);} 空白 操作员~() {删除全部();} 空白 删除(T*项目,布尔值删除=0){整数f=查找(项目);如果(f>-1) {{如果(del) {删除(项目);}别的{Append(item,mem);}}ReduceAt(f);}} 空白 删除最后一个(布尔值删除=0) {KillBad();如果(del) {删除(最后());}别的{追加(最后(),mem);}ReduceAt(数组大小(项目)-1);} 空白 首先删除(布尔值删除=0) {KillBad();如果(del) {删除(第一个());}别的{追加(第一个(),mem);}ReduceAt(0);} 空白 全部删除(布尔值删除=0); //堆栈接口 T* 顶部() {返回最后的();} 空白 推送(T*项目){追加(项目);} T* Pop() {T*top=Top();删除最后一个();返回顶部;}受保护的: T* 项目[]; T* mem[]; 布尔值 删除; //服务 空白 附加(T*项目,T*&dst[]){整数r=数组调整大小(夏令时,数组大小(夏令时)+1); dst[r-1]=项目;} 空白 清空内存() {为了(整数我=0;我<数组大小(内存); i++) {删除(mem[i]);}数组自由(内存);} 空白 删除(T*项目) {如果(检查指针(项目)==1)删除物品;} 空白 KillBad() {为了(整数我=0;我<数组大小(项目);我++){如果(项目[i]==无效的) {ReduceAt(i);我 - ;}}} 空白 减少 (整数); 空白 增加At(整数); 空白 复制(T*&dst[],T*&src[]) {整数c=数组大小(来源);数组调整大小(夏令时,c);为了(整数我=0;我 /**/
/********************************************************************
结构注释
默认情况下,当列表被销毁时,它会删除所有动态对象。
自动对象无论如何都会被破坏。
这意味着您不必对您创建的任何对象使用删除操作符。
一旦对象被添加到列表中,它就不会忘记它,
并能够访问它以在销毁时进行擦除。
从列表中删除的任何内容都会转移到回收站,
为了安全起见,保留“悬挂”指针,
从而最大限度地减少出现“错误指针访问”严重错误的机会。
在大多数情况下这是合理的,因为现在的计算机内存很大。
对效率也没有太大的负担,只有记忆力,虽然很小。
但是,为了灵活性,Remove 方法可以选择永久删除已删除的对象。
如果需要在列表销毁后保留对象(很少见),
使用 MemDelete 方法将 memdelete 标志设置为 false。
Remove 方法中的“del”参数是用于从内存中删除对象的标志。
对该对象的访问将不再可用,并将引发严重错误。
该列表仅保留对有效对象的引用,在访问/计数尝试时删除空指针。
但是,如果您使用带有指针返回的访问方法,并尝试访问错误的索引,
你会得到一个空指针,这意味着错误索引。
有一个经典的解决方法:TryGet 方法写入指针并告诉您
如果返回的指针有效,那么如果该方法返回 false,则不应使用该指针。
哈希方法返回 Mql 内部对象“哈希代码”,如您尝试打印对象/指针时所见。
我不确定这些代码是如何生成的,但它们在识别带有 == 的对象方面似乎相当可靠。
可用的运算符:
[索引] 获取,例如。类 T* 指针=list[3];
+= 追加,例如。列表+=指针; //列表+=&对象;
^= 前置,例如。列表^=指针; //列表+=&对象;
-= 删除,例如。列表-=指针; //列表+=&对象;
/= 删除并删除,例如。列表/=指针; //列表+=&对象;
〜删除全部,例如。 〜列表;
= 复制列表,例如。类列表A=列表B; //A-新的,B-现有的
/**/ /******************************************************************** ObjectList 使用示例 /********************************************************************/ 空白 启动时() { 对象列表列表; A*o1=新的B(); //动态的 A o2; //自动的 A*o3=&o2; //自动的 /**/ 列表+=&o2; //追加对象引用 列表^=o1; //前置 列表+=o3; //追加指针 列表.PrintHash(); //查看输出 /**/ {细绳s;为了(整数我=0;我<13; i++) {s+=“-”;}打印(s);} /**/ 列表-=&o2; //消除 ObjectListlist2=列表; //复制列表 list2.PrintHash(); //查看输出 /**/ {细绳s;为了(整数我=0;我<13; i++) {s+=“-”;}打印(s);} /**/ 〜列表; //清理列表,现在是空的 list2.RemoveLast(); //消除 list2.PrintHash(); //查看输出 /**/ {细绳s;为了(整数我=0;我<13; i++) {s+=“-”;}打印(s);} /**/ A* o=列表2[0]; //直接访问 打印(list2.Hash(o)); //2097152 // 相同... //在不检查的情况下使用 o 有风险,但如果你确定 打印(列表2.哈希(0)); //2097152 //...对象 打印(list2.TryGet(o,第666章));// false,不要使用o //安全访问 /** ...销毁时,列表将从内存中删除动态对象 o1。 /**/ }/******************************************************************** 输出: /** 0:2097152(A*) 1:3145728(A*) 2:3145728(A*) ------------- 0:2097152(A*) 1:3145728(A*) ------------- 0:2097152(A*) ------------- 2097152 2097152 假的 /**/
附件下载
📎 objectlist.mq5 (3.56 KB)
📎 objectlist.mqh (6.64 KB)
Source: MQL5 #29765
💡 精彩内容推荐
✍️ 楼主最新发布
- •
- •
- •
- •
- •
- •
🔗 您可能感兴趣
- •
- •
- •
- •
- •
- •
🔐
请登录后参与评论
注册满12小时后评论,即可解锁附件下载
立即登录
