文章 "在 MQL5 中使用对象指针" - 页 3 12345 新评论 Rashid Umarov 2014.01.23 07:42 #21 在这种情况下不要使用指针。 Vasiliy Sokolov 2014.01.23 07:50 #22 Barbarian2:我仍然不理解 MQL5 和 MQL4 中的指针和引用。除了额外的代码,引用传递和指针传递有什么区别?在 C++ 中是有区别的,但在这里有什么区别呢?如果不难写得更详细些。引用传递要求对引用传递的对象进行初始化。而通过指针传递则没有这种限制:class CShape { public: string name; }; void OnInit() { CShape* shape = NULL; TestShapePointer(shape); //Critical Error! TestShapeRef(shape); } void TestShapeRef(CShape& shape) { printf(shape.name); } void TestShapePointer(CShape* shape) { if(CheckPointer(shape) != POINTER_INVALID) printf(shape.name); } 调用 TestShapeRef函数 时,代码会因为形状未初始化而崩溃。另一方面,在 TestShapePointer 函数中,需要不断检查传递的对象是否初始化。因此,请遵循轻率原则:如果必须保证对象在传递给函数时已经存在,则使用"&"传递。如果函数需要一个状态未定义的对象,则使用 "*"指针传递,并在函数内部检查传递指针的有效性。还有一个细微的差别需要注意。请看前面的例子:class CShape { public: string name; }; void OnInit() { CShape* shape = NULL; TestShapePointer(shape); printf(shape.name); //ERROR (!?) } void TestShapePointer(CShape* shape) { if(CheckPointer(shape) == POINTER_INVALID) shape = new CShape(); printf(shape.name); } 这个程序能正常运行吗?不会,它将在printf(shape.name); //ERROR (!?) 行以 "无效指针访问 "错误结束,尽管我们似乎可以保证在 TestShapePointer 函数中创建一个对象。问题的关键在于,实际上传递的是一个 NULL 引用,而不是 shape。也就是说,函数内部的形状和传递的形状是不同的 对象!因此,在退出函数后,shape 仍然等于 NULL,而函数内部的形状指针则丢失了(在堆栈中被清除)。所以 Anatoli Kazharski 2014.11.05 14:47 #23 可以用不同类型的对象创建一个数组吗?让我们举这个例子://+------------------------------------------------------------------+ //|#Test.mq5 //| 2014 年 MetaQuotes 软件公司版权所有。 //|http://www.mql5.com | | //+------------------------------------------------------------------+ #property copyright "Copyright 2014, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" //--- #include <ChartObjects\ChartObjectsTxtControls.mqh> //--- CChartObjectRectLabel rect_label; CChartObjectButton button; CChartObjectEdit edit; //--- CChartObject *objects[]; //+------------------------------------------------------------------+ //| 脚本程序启动功能| //+------------------------------------------------------------------+ void OnStart() { edit.Create(0,"edit_1",0,20,20,100,20); button.Create(0,"button_1",0,20,40,100,20); rect_label.Create(0,"rect_label_1",0,20,60,100,20); //--- AddObjectToArray(edit); AddObjectToArray(button); AddObjectToArray(rect_label); //--- //objects[0].// 如何访问 CChartObjectEdit 类的方法? //objects[1].// 如何访问 CChartObjectButton 类的方法? //objects[2].// 如何访问 CChartObjectRectLabel 类的方法? //--- while(!IsStopped()) Sleep(1000); } //+------------------------------------------------------------------+ //| 返回对象的数量| //+------------------------------------------------------------------+ int ElementsTotal() { return(ArraySize(objects)); } //+------------------------------------------------------------------+ //|| 向数组添加一个对象| //+------------------------------------------------------------------+ void AddObjectToArray(CChartObject &object) { int size=ElementsTotal(); //--- ArrayResize(objects,size+1); objects[size]=GetPointer(object); //--- if(CheckPointer(objects[size])!=POINTER_INVALID) Print(__FUNCSIG__," >>> array["+IntegerToString(size)+"]: ",objects[size].Name(), "; object type: ",ObjectTypeToString(objects[size].Type())); } //+------------------------------------------------------------------+ //| 将对象类型转换为字符串| //+------------------------------------------------------------------+ string ObjectTypeToString(int type) { string str=""; //--- switch((ENUM_OBJECT)type) { case OBJ_EDIT : return("edit"); break; case OBJ_BUTTON : return("button"); break; case OBJ_RECTANGLE_LABEL : return("rectangle label"); break; } //--- return("undefined object type"); } //+------------------------------------------------------------------+ //---如何访问 继承类的方法? Rashid Umarov 2014.11.05 15:03 #24 tol64:如何访问 继承类的方法? 您是否尝试过向目标类型转换? Anatoli Kazharski 2014.11.05 15:06 #25 Rosh: 你试过施放目标类型吗? 没有,第一次听说。我在哪里可以读到? Ilyas 2014.11.05 16:34 #26 tol64: 没有,我还是第一次听说。我在哪里可以读到? 这是一个常见的形容词类型,这里有一个例子://+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ class CFoo { }; //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ class CBar : public CFoo { public: void func(int x) { Print("Hello from Bar ",x); } }; //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ void func(CFoo *foo) { //--- 直接从指针到基本类型的转换调用 ((CBar*)foo).func(1); //--- 调用时转换为目标类型,并以所需类型保存指针副本 CBar *b=(CBar *)foo; b.func(2); //--- 删除动态创建的类 delete foo; } //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ void OnStart() { func(new CBar); } //+------------------------------------------------------------------+ Anatoli Kazharski 2014.11.05 16:44 #27 mql5: 通常的类型转换,这里有一个例子: 谢谢。我会研究一下的。 TheXpert 2014.11.05 18:26 #28 Rosh: 你试过向目标类型施法吗? 妈的,然后你就开始谈论语言安全了? Anatoli Kazharski 2014.11.05 18:34 #29 TheXpert: 妈的,这之后你还谈语言安全? 你找到安全漏洞了吗?) Denis Kirichenko 2014.11.06 07:28 #30 使用多态性 不是更好吗?是这样的CChartObject *ptr_rect_label; CChartObject *ptr_button; CChartObject *ptr_edit; CChartObject *objects[]; //--- ptr_rect_label=new CChartObjectRectLabel; ptr_button=new CChartObjectButton; ptr_edit=new CChartObjectEdit; 12345 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
我仍然不理解 MQL5 和 MQL4 中的指针和引用。除了额外的代码,引用传递和指针传递有什么区别?在 C++ 中是有区别的,但在这里有什么区别呢?如果不难写得更详细些。
引用传递要求对引用传递的对象进行初始化。而通过指针传递则没有这种限制:
调用 TestShapeRef函数 时,代码会因为形状未初始化而崩溃。另一方面,在 TestShapePointer 函数中,需要不断检查传递的对象是否初始化。因此,请遵循轻率原则:
还有一个细微的差别需要注意。请看前面的例子:
这个程序能正常运行吗?不会,它将在printf(shape.name); //ERROR (!?) 行以 "无效指针访问 "错误结束,尽管我们似乎可以保证在 TestShapePointer 函数中创建一个对象。问题的关键在于,实际上传递的是一个 NULL 引用,而不是 shape。也就是说,函数内部的形状和传递的形状是不同的 对象!因此,在退出函数后,shape 仍然等于 NULL,而函数内部的形状指针则丢失了(在堆栈中被清除)。所以可以用不同类型的对象创建一个数组吗?
让我们举这个例子:
//---
如何访问 继承类的方法?
如何访问 继承类的方法?
你试过施放目标类型吗?
没有,我还是第一次听说。我在哪里可以读到?
通常的类型转换,这里有一个例子:
你试过向目标类型施法吗?
妈的,这之后你还谈语言安全?
使用多态性 不是更好吗?
是这样的