mql5中的OOP、模板和宏,细微之处和用途 - 页 2 123456789...28 新评论 Alexey Navoykov 2019.01.24 18:31 #11 Ilya Malev:我遇到过很多在全局初始化的类中声明静态字段的情况(在OnInit之前),只要你在类描述之后,在声明其实例的全局变量 之前重新声明静态字段,静态字段的初始化就不会有任何问题(因为在这种情况下,按照我的理解,它被认为是全局的,在类实例之前初始化)。也就是说,你只需要拒绝在方法和函数里面声明静态变量就没有问题了。是的,这是正确的,在常规类中,它被立即初始化。但它在模板中没有被初始化。 template<typename T> class A { public: static int a; }; template<typename T> int A::a=10; int f() { return A<int>::a; } int a= f(); void OnStart() { Print(a); // Результат: 0 }; Alexey Navoykov 2019.01.24 18:54 #12 Alexey Viktorov:你不能完全拒绝在方法和函数中声明静态变量,但至少不要用那些包含静态变量的方法或函数初始化其他静态变量。 在这个例子中,一开始静态int b变量将被初始化,但int a(int n)函数中的静态int f变量还没有被初始化,结果我们会得到胡言乱语。顺便说一句,是的,这又是一个bug。 即除了静态/全局变量的单独初始化,代码以错误的顺序初始化静态变量 本身。所以你说 "不要用那些包含静态变量的方法或函数来 初始化其他静态变量"--你实际上是如何建议遵守这一点的? 每个函数都是独立的,都是自己存在 的。它有自己的实施方式,可能会有变化。 假设它以前没有静态变量,然后你决定添加它,这意味着某处可能会出错,因为它的设计中没有静态变量的函数。 那么你要如何控制这一切呢? Alexey Navoykov 2019.01.24 19:04 #13 我不明白这种放弃这个或那个的决定。为什么要放弃? 为什么? 当你能解决这个问题,并且不否定自己的时候。 那么,每个人都有自己的选择...... Alexey Viktorov 2019.01.24 19:11 #14 Alexey Navoykov:顺便说一下,是的,这是另一个bug,即除了单独初始化静态/全局重测,它还以错误的顺序初始化静态变量 本身。所以你说 "不要用那些包含静态变量的方法或函数来 初始化其他静态变量"--你实际上是如何建议遵守这一点的? 每个函数都是独立的,都是自己存在 的。它有自己的实施方式,可能会有变化。 假设它以前没有静态变量,然后你决定添加它,这意味着某处可能会出错,因为它的设计中没有静态变量的函数。 那么你要如何控制这一切呢?这根本不是一个问题。拒绝用函数初始化变量就足够了,一切都将归于平静。 int a(int n) { static int f=7; return(f+=n); } void OnTick() { static int b; b=a(9); } 它可以正常工作。有什么问题呢?一条线? Alexey Navoykov 2019.01.24 19:16 #15 Alexey Viktorov:它可以为呼声和呼唤而工作。有什么问题呢?一条线? 那么你是否理解这里的逻辑是不同的? 如果你在每次调用时都给它赋值,为什么还要把b声明为静态? Alexey Viktorov 2019.01.24 19:41 #16 Alexey Navoykov: 那么,你是否理解这里的逻辑是不同的? 如果你在每次调用时都给它赋值,为什么要声明b是静态的?我同意。我在匆忙中搞砸了一点。但是'b'变量可以在某些条件下被分配一个值,而不是9个值,可以根据条件传入函数。 但在你的例子中,'a'变量是否必须全局初始化? template<typename T> class A { public: static int a; }; template<typename T> int A::a=10; int f() { return A<int>::a; } int a= f(); void OnStart() { Print(a); // Результат: 0 }; 脚本中没有其他选项,在Expert Advisor中,你可以在全局层面声明该变量,并在OnInit()中初始化它。 了解并观察初始化顺序就足够了。首先是全局变量,然后是静态变量,最后是代码中出现的局部变量。 这个例子就违反了文档中关于不要用函数初始化变量 的建议。对开发者来说,写这样的警告比解释哪里可以、哪里不可以更容易。 从你的例子中删除静态的东西,得到你想要的结果。 Alexey Navoykov 2019.01.24 19:54 #17 Alexey Viktorov:但是,你的样本中的'a'变量必须是全局初始化的吗? 不一定,但对我来说更方便。 如果它是一个常量(全局可见的常量大多被声明,如果代码很聪明的话),那么就没有其他选择。 脚本中没有其他选项,在EA中你可以 全局声明一个变量并在OnInit()中初始化它。 了解并观察 初始化顺序就足够了。首先是全局变量,然后是静态变量,最后是代码中出现的局部变量。 这个例子就违反了文档中关于不要用函数初始化变量 的建议。对开发者来说,写这样的警告比解释哪里可以、哪里不可以更容易。 从你的例子中去掉 静态的东西,就可以得到理想的结果。 关于黄色的一切,我有一个问题:为什么?我已经找到了解决这个问题的方法。 Alexey Navoykov 2019.01.24 20:17 #18 更新了前页的文件。纠正了一个小缺陷。 Алексей Тарабанов 2019.01.24 20:34 #19 Alexey Navoykov: 不一定,但对我来说更方便。 如果它是一个常量(而全局可见性大多声明常量,如果代码是合格的),这里没有其他选择。 关于黄色的一切,我有一个问题:为什么?我已经找到了解决这个问题的方法。你已经找到了一个创造它的方法。 Ilya Malev 2019.01.24 20:43 #20 Alexey Navoykov:是的,没错,在普通类中,它被立即初始化。但在模板类中则不然。 你试图在初始化阶段使用一个类 的静态字段,而该类至少有一个实例被创建。在我看来,这是一种变态...这就是它的正常工作方式。 template<typename T> class A { public: A(){} static int a; int f(){return a;} }; template<typename T> int A::a=10; A<int> _a; int a= _a.f(); void OnStart() { Print(a); }; 一般来说,封装的原则表明,这种字段应该是隐藏的,而不是公开的。 123456789...28 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
我遇到过很多在全局初始化的类中声明静态字段的情况(在OnInit之前),只要你在类描述之后,在声明其实例的全局变量 之前重新声明静态字段,静态字段的初始化就不会有任何问题(因为在这种情况下,按照我的理解,它被认为是全局的,在类实例之前初始化)。也就是说,你只需要拒绝在方法和函数里面声明静态变量就没有问题了。
是的,这是正确的,在常规类中,它被立即初始化。但它在模板中没有被初始化。
你不能完全拒绝在方法和函数中声明静态变量,但至少不要用那些包含静态变量的方法或函数初始化其他静态变量。
在这个例子中,一开始静态int b变量将被初始化,但int a(int n)函数中的静态int f变量还没有被初始化,结果我们会得到胡言乱语。顺便说一句,是的,这又是一个bug。 即除了静态/全局变量的单独初始化,代码以错误的顺序初始化静态变量 本身。所以你说 "不要用那些包含静态变量的方法或函数来 初始化其他静态变量"--你实际上是如何建议遵守这一点的? 每个函数都是独立的,都是自己存在 的。它有自己的实施方式,可能会有变化。 假设它以前没有静态变量,然后你决定添加它,这意味着某处可能会出错,因为它的设计中没有静态变量的函数。 那么你要如何控制这一切呢?
顺便说一下,是的,这是另一个bug,即除了单独初始化静态/全局重测,它还以错误的顺序初始化静态变量 本身。所以你说 "不要用那些包含静态变量的方法或函数来 初始化其他静态变量"--你实际上是如何建议遵守这一点的? 每个函数都是独立的,都是自己存在 的。它有自己的实施方式,可能会有变化。 假设它以前没有静态变量,然后你决定添加它,这意味着某处可能会出错,因为它的设计中没有静态变量的函数。 那么你要如何控制这一切呢?
这根本不是一个问题。拒绝用函数初始化变量就足够了,一切都将归于平静。
它可以正常工作。有什么问题呢?一条线?它可以为呼声和呼唤而工作。有什么问题呢?一条线?
那么,你是否理解这里的逻辑是不同的? 如果你在每次调用时都给它赋值,为什么要声明b是静态的?
我同意。我在匆忙中搞砸了一点。但是'b'变量可以在某些条件下被分配一个值,而不是9个值,可以根据条件传入函数。
但在你的例子中,'a'变量是否必须全局初始化?
脚本中没有其他选项,在Expert Advisor中,你可以在全局层面声明该变量,并在OnInit()中初始化它。
了解并观察初始化顺序就足够了。首先是全局变量,然后是静态变量,最后是代码中出现的局部变量。
这个例子就违反了文档中关于不要用函数初始化变量 的建议。对开发者来说,写这样的警告比解释哪里可以、哪里不可以更容易。
从你的例子中删除静态的东西,得到你想要的结果。
但是,你的样本中的'a'变量必须是全局初始化的吗?
不一定,但对我来说更方便。 如果它是一个常量(全局可见的常量大多被声明,如果代码很聪明的话),那么就没有其他选择。
脚本中没有其他选项,在EA中你可以 全局声明一个变量并在OnInit()中初始化它。
了解并观察 初始化顺序就足够了。首先是全局变量,然后是静态变量,最后是代码中出现的局部变量。
这个例子就违反了文档中关于不要用函数初始化变量 的建议。对开发者来说,写这样的警告比解释哪里可以、哪里不可以更容易。
从你的例子中去掉 静态的东西,就可以得到理想的结果。
不一定,但对我来说更方便。 如果它是一个常量(而全局可见性大多声明常量,如果代码是合格的),这里没有其他选择。
关于黄色的一切,我有一个问题:为什么?我已经找到了解决这个问题的方法。你已经找到了一个创造它的方法。
是的,没错,在普通类中,它被立即初始化。但在模板类中则不然。
你试图在初始化阶段使用一个类 的静态字段,而该类至少有一个实例被创建。在我看来,这是一种变态...这就是它的正常工作方式。
一般来说,封装的原则表明,这种字段应该是隐藏的,而不是公开的。