关于OOP(面向对象的编程)的问题 - 页 6 1234567891011 新评论 Vadim Zhunko 2014.04.15 20:11 #51 C-4: 在需要动态类型识别的复杂对象转换中,指针是不可缺少的。 瓦西里,请举个例子! 我只知道有一种情况,你需要分配内存并需要一个指针。 我相信你几乎总是可以不用它。最好不要使用手动内存管理。总有一个标准库 已经在处理这些问题。 Александр 2014.04.15 20:32 #52 Integer: 有一条原则在任何地方都适用:每件事都必须尽可能简单地完成。你不需要为了进入事情的漩涡而进入事情的漩涡。如果一个问题可以简单解决,就应该简单解决。 正是如此。而这正是正确设计班级的重要之处。而要做到这一点,重要的是要预测下一个阶层(后裔)会是什么。 通常情况下,基类应该有最低限度的功能,但最好是创建大量的虚拟方法,以设定类的使用矢量。 在MQL的情况下--可能正好相反--基类中有更多的功能,就像在VOLDEMAR 中。但是没有狂热。 有贸易符号属性(POINT、STOPLEVEL等)。MODE_XXX 用于MarketInfo())。我们最好把它们塞进cSymbol 类,比如说。 有订单属性(开盘价、类型、手数等)。OrderXXX())。例如,把它们放到一个单独的cOrder 类中会更好。 如果我们记得订单可以分部分关闭,那么我们也应该把BaseLot 字段分配给该类(以便知道哪一部分已经关闭),以此类推。 有(对我来说)一个时间表--指定的时间段(按天计算),我们可以开仓和平仓,只平仓的时间段(如果已经盈亏平衡,则追踪),还有一个时间段,我们完全不工作,然后关闭所有开仓和删除未开仓订单。 请记住关于差距,在许多(如果不是全部)经纪公司的最后一个小时的交易中,可能会改变交易条件,许多经纪公司在每个交易日都有一个交易金属的休息时间。 最后,还有一个EA--一个特定的算法,在特定的时间表上,用特定的 "其 "订单列表和自己的数据进行计算,对特定的符号工作。 我们可以创建一个cExpert 类,它将包含一个cSymbol 类的对象和 一个cOrder 类的对象阵列。这个基本的cExpert 将包含更新cOrder 对象属性的功能,订单处理的功能,错误处理,统计等。 我个人认为,以AccountFreeMargin() 的%计算手数,为每个订单生成一个独特的magik(更容易把反向订单放到一个特定的订单上),下反向订单的功能,等等,都很有用。 而这正是cExpert 可以降生的地方,独特的附加数据集和功能将决定在市场上做什么(开仓/公司/平仓订单)。 即实施交易策略。而这将是我们所说的 "XXX战略EA"。 但所有的 基本功能 都在基础的cExpert 类中。子类将包含交易策略的算法。 好吧,也许有人会在交易中加入一些高级错误处理或高级统计(如果没有源代码,而且不能塞进基本的cExpert)。 请注意,我们正在花时间,创建一个将简化编写EA的类。事实上,它是一个专家顾问模板。结构上完整,没有刷子(所有必要的数据与代码放在一起)。 至于所谓的包装函数比openorders() "多余 "的问题,我个人只是支持这样的包装函数(尤其是--如果它们有额外的功能,而不仅仅是调用基本函数)。 例如,如果在调用包装器时,SL和 TP 是以点为单位指定的,我们必须将它们转换为绝对数字,而且还要根据顺序类型进行加减(尽管在这种情况下,这种转换也可以放在operorders()中)。 我个人认为,理解调用BuyStop(...) 的代码并检查一次BuyStop() 是否做得正确,比每次解析OrderSend() 参数的正确性要容易。 PS:这是一个很大的工作,包括在周末。感谢Pavlick和 mql5 提供的示例代码。 看看这些例子,想一想,真的有必要在编程任务领域创建一个类的层次结构吗,这是用MQL写的? 你真的需要在一个基本的基础上有一整个系列的课程吗(所有这些 "三角形"、"正方形 "等等)? 再一次引用Integer 的金句:不要为了 进入灌木丛而进入灌木丛。 哦,要么是我没注意到,要么是最近出现了带例子的文档 部分。 Александр 2014.04.15 21:07 #53 Zhunko: 我只知道有一种情况,你需要分配内存并需要一个指针。 我相信你几乎总是可以不用它。建议不要使用手动内存管理。总有一个标准库已经解决了这些问题。 这里可能是它的全部内容。 我们假设有一个cFather 类,它有 int GetData() 方法,返回3。还有方法 PrintData(),它输出从GetData() 得到的东西。 它的后代cChild 已经重写了GetData(),现在返回5。 如果我们声明一个cFather 类型的对象为TestObject,那么TestObject.GetData()将总是返回3。 如果我们声明cFather* TestObject=new cChild1,那么TestObject.GetData()将返回5,尽管它看起来是cFather。 需要这样做,以便现在编写的代码可以在cFather 类的任何后裔上调用GetData() 方法,即使它(后裔类)还不存在。 也就是说,如果这时出现了cChild2 类,用它的GetData() 将返回7,那么在cFather* Test2=new cChild2 函数Test2.PrintData() 后将开始输出7。 如果有一些函数期望一个 "对cFather 类对象的引用 "的参数并使用它GetData(),它将获得任何 cFather 后代的正确数据。 方法绑定发生在调用new 的时候。如果它没有被引用,那么绑定将是硬性的,也就是说,声明的类的方法将被调用。 见这里 和这里 Vadim Zhunko 2014.04.15 21:28 #54 EverAlex: 这似乎是它的全部内容。... 有一个":: "操作符,允许你访问整个基类 和派生类 链中的任何方法,而无需分配内存或指针。 Vladimir Pastushak 2014.04.16 04:56 #55 C-4: 你的课90%都是多余的。只有两个函数做主要工作,这两个函数是openorders 和 tip 为什么你用Sel、Buy SelStop等,而事实上它们都只是调用Openorders?此外,订单类型是以int形式传递的,所以它不受保护。你最好使用你自己的枚举或标准的ENUM_ORDER_TYPE来代替int。而且一般来说,你最好永远不要使用神奇的数字 "1"、"2 "等,只使用枚举。这将防止你向函数发送左边的订单值。开放边界函数本身太大。很明显,它由两个部分组成,即进行交易的部分和检查条件的部分。每一个都应该是一个独立的私人职能。这是一个良好的开端,但我们仍有很多东西需要学习。提示函数最好改写如下。在调用该方法时,我可以直观地看到我下的是什么类型的订单,这很方便... 关于比较,请详细描述为什么不建议用0来比较双数? TheXpert 2014.04.16 04:59 #56 C-4: 在需要动态类型识别的复杂对象转换中,指针是不可缺少的。 动态类型识别的存在通常表明一个项目的 拐杖结构。 keekkenen 2014.04.16 05:38 #57 如果在EA中全局地声明一个类(Class c;),那么在一次打勾时改变的内部类对象 的状态会在下一次打勾时保存吗? [删除] 2014.04.16 05:50 #58 EverAlex: 这似乎就是它的意义所在。 假设有一个cFather 类,它有 int GetData()方法,返回3。还有方法 PrintData(),它输出从GetData() 得到的东西。 还有它的后代cChild,它已经重写了GetData(),现在返回5。 如果我们声明一个cFather 类型的对象为TestObject,那么TestObject.GetData()将总是返回3。 如果我们声明cFather* TestObject=new cChild1,那么TestObject.GetData()将返回5,尽管它看起来是cFather。 需要这样做,以便现在编写的代码可以在cFather 类的任何后裔上调用GetData() 方法,即使它(后裔类)还不存在。 也就是说,如果这时出现了cChild2 类,用它的GetData() 将返回7,那么在cFather* Test2=new cChild2 函数Test2.PrintData() 后将开始输出7。 如果有一些函数期望一个 "对cFather 类对象的引用 "的参数并使用它GetData(),它将获得任何 cFather 后代的正确数据。 方法绑定发生在调用new 的时候。如果它没有被引用,那么绑定将是硬性的,也就是说,声明的类的方法将被调用。 见这里 和这里 class cFather { public: int GetData() {return 3;} }; class cChild : public cFather { public: int GetData() {return 5;} }; int f(cFather *p) {return p->GetData();} int main() { cChild obj; f(&obj); // вернет 3 obj.cFather::GetData(); // вернет 3 return 0; } [删除] 2014.04.16 06:10 #59 Pavlick: 也许我写的这个例子是白写的。它在MKL中不起作用。 cChild obj; f(&obj); // вернет 3 obj.cFather::GetData(); // вернет 3 H.k.,不是指点江山,而是笑里藏刀。 P.S:用dlls写,有机会学习正常的语言。 Ilyas 2014.04.16 06:27 #60 Pavlick: 也许我写的这个例子是白写的。它在MKL中不起作用。 H.k.,不是指点江山,而是笑里藏刀。 P.S:用dlls写,有机会学习正常的语言。 class cFather { public: int GetData() {return 3;} }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cChild : public cFather { public: int GetData() {return 5;} }; int f(cFather *p) {return p.GetData();} //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnStart() { cChild obj,*ptr=GetPointer(obj); f(ptr); // вернет 3 ((cFather *)ptr).GetData(); // вернет 3 return 0; } 1234567891011 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
在需要动态类型识别的复杂对象转换中,指针是不可缺少的。
瓦西里,请举个例子!
我只知道有一种情况,你需要分配内存并需要一个指针。
我相信你几乎总是可以不用它。最好不要使用手动内存管理。总有一个标准库 已经在处理这些问题。
有一条原则在任何地方都适用:每件事都必须尽可能简单地完成。你不需要为了进入事情的漩涡而进入事情的漩涡。如果一个问题可以简单解决,就应该简单解决。
正是如此。而这正是正确设计班级的重要之处。而要做到这一点,重要的是要预测下一个阶层(后裔)会是什么。
通常情况下,基类应该有最低限度的功能,但最好是创建大量的虚拟方法,以设定类的使用矢量。
在MQL的情况下--可能正好相反--基类中有更多的功能,就像在VOLDEMAR 中。但是没有狂热。
有贸易符号属性(POINT、STOPLEVEL等)。MODE_XXX 用于MarketInfo())。我们最好把它们塞进cSymbol 类,比如说。
有订单属性(开盘价、类型、手数等)。OrderXXX())。例如,把它们放到一个单独的cOrder 类中会更好。
如果我们记得订单可以分部分关闭,那么我们也应该把BaseLot 字段分配给该类(以便知道哪一部分已经关闭),以此类推。
有(对我来说)一个时间表--指定的时间段(按天计算),我们可以开仓和平仓,只平仓的时间段(如果已经盈亏平衡,则追踪),还有一个时间段,我们完全不工作,然后关闭所有开仓和删除未开仓订单。
请记住关于差距,在许多(如果不是全部)经纪公司的最后一个小时的交易中,可能会改变交易条件,许多经纪公司在每个交易日都有一个交易金属的休息时间。
最后,还有一个EA--一个特定的算法,在特定的时间表上,用特定的 "其 "订单列表和自己的数据进行计算,对特定的符号工作。
我们可以创建一个cExpert 类,它将包含一个cSymbol 类的对象和 一个cOrder 类的对象阵列。这个基本的cExpert 将包含更新cOrder 对象属性的功能,订单处理的功能,错误处理,统计等。
我个人认为,以AccountFreeMargin() 的%计算手数,为每个订单生成一个独特的magik(更容易把反向订单放到一个特定的订单上),下反向订单的功能,等等,都很有用。
而这正是cExpert 可以降生的地方,独特的附加数据集和功能将决定在市场上做什么(开仓/公司/平仓订单)。
即实施交易策略。而这将是我们所说的 "XXX战略EA"。
但所有的 基本功能 都在基础的cExpert 类中。子类将包含交易策略的算法。
好吧,也许有人会在交易中加入一些高级错误处理或高级统计(如果没有源代码,而且不能塞进基本的cExpert)。
请注意,我们正在花时间,创建一个将简化编写EA的类。事实上,它是一个专家顾问模板。结构上完整,没有刷子(所有必要的数据与代码放在一起)。
至于所谓的包装函数比openorders() "多余 "的问题,我个人只是支持这样的包装函数(尤其是--如果它们有额外的功能,而不仅仅是调用基本函数)。
例如,如果在调用包装器时,SL和 TP 是以点为单位指定的,我们必须将它们转换为绝对数字,而且还要根据顺序类型进行加减(尽管在这种情况下,这种转换也可以放在operorders()中)。
我个人认为,理解调用BuyStop(...) 的代码并检查一次BuyStop() 是否做得正确,比每次解析OrderSend() 参数的正确性要容易。
PS:这是一个很大的工作,包括在周末。感谢Pavlick和 mql5 提供的示例代码。
看看这些例子,想一想,真的有必要在编程任务领域创建一个类的层次结构吗,这是用MQL写的?
你真的需要在一个基本的基础上有一整个系列的课程吗(所有这些 "三角形"、"正方形 "等等)?
再一次引用Integer 的金句:不要为了 进入灌木丛而进入灌木丛。
哦,要么是我没注意到,要么是最近出现了带例子的文档 部分。
我只知道有一种情况,你需要分配内存并需要一个指针。
我相信你几乎总是可以不用它。建议不要使用手动内存管理。总有一个标准库已经解决了这些问题。
这里可能是它的全部内容。
我们假设有一个cFather 类,它有 int GetData() 方法,返回3。还有方法 PrintData(),它输出从GetData() 得到的东西。
它的后代cChild 已经重写了GetData(),现在返回5。
如果我们声明一个cFather 类型的对象为TestObject,那么TestObject.GetData()将总是返回3。
如果我们声明cFather* TestObject=new cChild1,那么TestObject.GetData()将返回5,尽管它看起来是cFather。
需要这样做,以便现在编写的代码可以在cFather 类的任何后裔上调用GetData() 方法,即使它(后裔类)还不存在。
也就是说,如果这时出现了cChild2 类,用它的GetData() 将返回7,那么在cFather* Test2=new cChild2 函数Test2.PrintData() 后将开始输出7。
如果有一些函数期望一个 "对cFather 类对象的引用 "的参数并使用它GetData(),它将获得任何 cFather 后代的正确数据。
方法绑定发生在调用new 的时候。如果它没有被引用,那么绑定将是硬性的,也就是说,声明的类的方法将被调用。
见这里 和这里
这似乎是它的全部内容。
...
你的课90%都是多余的。只有两个函数做主要工作,这两个函数是openorders 和 tip 为什么你用Sel、Buy SelStop等,而事实上它们都只是调用Openorders?此外,订单类型是以int形式传递的,所以它不受保护。你最好使用你自己的枚举或标准的ENUM_ORDER_TYPE来代替int。而且一般来说,你最好永远不要使用神奇的数字 "1"、"2 "等,只使用枚举。这将防止你向函数发送左边的订单值。开放边界函数本身太大。很明显,它由两个部分组成,即进行交易的部分和检查条件的部分。每一个都应该是一个独立的私人职能。
这是一个良好的开端,但我们仍有很多东西需要学习。提示函数最好改写如下。
在调用该方法时,我可以直观地看到我下的是什么类型的订单,这很方便...
关于比较,请详细描述为什么不建议用0来比较双数?
在需要动态类型识别的复杂对象转换中,指针是不可缺少的。
这似乎就是它的意义所在。
假设有一个cFather 类,它有 int GetData()方法,返回3。还有方法 PrintData(),它输出从GetData() 得到的东西。
还有它的后代cChild,它已经重写了GetData(),现在返回5。
如果我们声明一个cFather 类型的对象为TestObject,那么TestObject.GetData()将总是返回3。
如果我们声明cFather* TestObject=new cChild1,那么TestObject.GetData()将返回5,尽管它看起来是cFather。
需要这样做,以便现在编写的代码可以在cFather 类的任何后裔上调用GetData() 方法,即使它(后裔类)还不存在。
也就是说,如果这时出现了cChild2 类,用它的GetData() 将返回7,那么在cFather* Test2=new cChild2 函数Test2.PrintData() 后将开始输出7。
如果有一些函数期望一个 "对cFather 类对象的引用 "的参数并使用它GetData(),它将获得任何 cFather 后代的正确数据。
方法绑定发生在调用new 的时候。如果它没有被引用,那么绑定将是硬性的,也就是说,声明的类的方法将被调用。
见这里 和这里
也许我写的这个例子是白写的。它在MKL中不起作用。
H.k.,不是指点江山,而是笑里藏刀。
P.S:用dlls写,有机会学习正常的语言。
也许我写的这个例子是白写的。它在MKL中不起作用。
H.k.,不是指点江山,而是笑里藏刀。
P.S:用dlls写,有机会学习正常的语言。