MQL5中的OOP问题 - 页 83 1...767778798081828384858687888990...96 新评论 Vladimir Simakov 2020.06.14 06:44 #821 呀...人们对const(((())是多么的混乱。 要理解带有const指定符的方法 class CTest{ int i; public: CTest(int _i):i(_i){} int Get() const {return i;} int Get() {return 2*i;} }; void OnStart() { const CTest a(5); CTest b(8); Print(a.Get()); //5 Print(b.Get()); //16 } 现在做 //int Get() const {return i;} 然后反之亦然。 // int Get() {return 2*i;} ))) Vladimir Simakov 2020.06.14 07:03 #822 Alexandr Andreev:也是同一代码的一个变体。这是与常数有关的。 而且你确信,输入的 Compare(CObject const *node,int const mode=0) 你会一直喂养 CChartObjectRectangleX* 不检查就写? return ( Time(1)-dynamic_cast<const ME*>(node).Time(1)); ? Aleksey Mavrin 2020.06.14 14:04 #823 Alexandr Andreev:由于基类没有对输入参数的引用,所以没有宪法 的变体也能正确工作,尽管这种风格不是很聪明 这样做是行不通的。你不能改变比较中的签名。这主要是SB中包含的QuickSort方法所需要的,它可以使常规排序工作。 如果你改变签名,它就不是虚函数的覆盖,而是重载,它调用基类CObject 的方法,返回0。 当然,这可以通过对容器的包装(装饰)来解决,但为什么要做这些不必要的动作,否则就不要用SB,一切从头开始写。 Aleksey Mavrin 2020.06.14 14:21 #824 Vladimir Simakov:它似乎与你的相同,只是字母较少。因此,这是一个品味问题,但我删除了额外的变量(很可能,编译器会将其作为优化的一部分而删除)。关于我的!节点检查。必须用CheckPointer(node)==POINTER_INVALID来代替, 但这是一个开销--一个函数调用。即使它是内联的,它至少也是在取消引用和检查状态标志。如果只是库或具体的,你写的程序将使用比较方法,最好!节点和代码上的无效指针。如果你懒得注意指针,或者这是一个为弱者准备的库,只有CheckPointer(node)==POINTER_INVALID。如果你删除了你强调的const指定符,你就不能从一个常量对象 中调用这些方法。UPD:可以删除突出显示的检查,因为它是在被调用的方法中。 Vladimir,只是在这种情况下CheckPointer是多余的。 dynamic_cast会在任何失败的cast中返回NULL,包括指针被破坏的情况。如果我说错了,请纠正我。很久以前测试过,测试时间为5秒)。 CheckPointer的工作机制(简单的说,我不太懂低级别的术语)--它通过指针寻找什么样的对象,动态的还是静态的,如果我们不能得到信息,就意味着POINTER_INVALID。这可能是在动态对象被删除的情况下,其他情况我不知道,或者上传垃圾到指针,但必须检查编译器,如果你找不到漏洞。 和dynamic_cast做同样的事情,同时检查指针是否可以被投到所需的类型,即它是否是这个类型的指针或子类的指针。 如果指针被破坏,dynamic_cast无法检测到任何东西并返回NULL。 这就是为什么我没有使用CheckPointer。但我通常在任何地方都使用这种检查,以避免受到伤害。毕竟,要在软件中找到一个错误,这是不倒的,似乎有点容易)。 而非const - 理论上我们可以有一个类似GetRatingByAnyFormula()的方法 { m_rating01=Formula01(); return m_rating01;}。 如果不立即用于排序,将相当不方便,也就是说,我们必须先计算评级,然后再调用按评级排序。或者,正如已经说过的,从头开始写你自己的SB)。 Alexandr Andreev 2020.06.14 14:30 #825 Aleksey Mavrin:这不是好事。签名不能在比较中改变。这主要是为了让SB中包含的常规排序方法QuickSort发挥作用。如果你改变了签名,就不是对虚函数的覆盖,而是重载,基类CObject 的方法将被调用,其中返回0。 当然,这可以通过对容器的包装(装饰)来解决,但为什么要做这些不必要的动作,或者不使用SB而从头开始写一切? 最正确的方法是不在µl上写字 Vladimir Simakov 2020.06.14 18:06 #826 Aleksey Mavrin:Vladimir,在这种情况下,CheckPointer是多余的。 dynamic_cast将在任何不成功的投掷中返回NULL,包括指针被破坏的情况。如果我说错了,请纠正我。很久以前测试过,测试时间为5秒)。CheckPointer的工作机制(简单的说,我不太懂低级别的术语)--它通过指针寻找什么样的对象,动态的还是静态的,如果我们不能得到信息,就意味着POINTER_INVALID。这可能是在动态对象被删除的情况下,其他情况我不知道,或者上传垃圾到指针,但必须检查编译器,如果你找不到漏洞。和dynamic_cast做同样的事情,同时检查指针是否可以被投到所需的类型,即它是否是这个类型的指针或子类的指针。 如果指针被破坏,dynamic_cast无法检测到任何东西并返回NULL。 这就是为什么我没有使用CheckPointer。但我通常在任何地方都使用这种检查,以避免受到伤害。毕竟,要在软件中找到一个错误,这是不倒的,似乎有点容易)。而非const - 理论上我们可以有一个类似GetRatingByAnyFormula()的方法 { m_rating01=Formula01(); return m_rating01;}。如果不立即用于排序,将相当不方便,也就是说,我们必须先计算评级,然后再调用按评级排序。或者你可以像前面提到的那样从头开始写你自己的SB)。 比较方法被定义为公共的,这意味着任何劣势者,无论你在规范中如何努力解释,都会把一个无效的描述符推到那里。当然,如果不是图书馆,只是为了自己,你也不必如此。 我不知道CheckPointer 是如何工作的,它的工作原理是。但无论如何,它是处理器的时钟和内存访问(它很容易变成虚拟内存)。 关于带有const指定符的方法。如果你写一个库,你必须始终牢记,对象可能需要一个常量,所以在那些方法中,不改变对象的状态,因为它是可取的。虽然到目前为止,对我自己来说,我并没有真正去理会它。 编写你自己的系统,这可能是正确的决定。这只是有趣的前景,在薪酬/劳动比例上还看不到,因此也不会完成,所以只为自己的需要)。 Alexey Navoykov 2020.06.14 19:03 #827 Vladimir Simakov:关于我的!节点检查。它应该被CheckPointer(node)==POINTER_INVALID取代,但这是一个开销,函数调用。 问题不在于开销,而在于破损的指针会改变程序的逻辑。 也就是说,你不但没有发现问题,反而会把它埋得更深。 CheckPointer 应该只用于调试目的,或者作为弱指针的实现。 Aleksey Mavrin 2020.06.15 07:38 #828 Vladimir Simakov: 比较方法被定义为公共的,所以任何劣势者,无论你在规范中如何告诉他,都会把一个无效的描述符塞到那里(让我们用正确的名字称呼事物)。当然,如果不是图书馆,只是为了自己,你也不必如此。 我不知道CheckPointer是如何工作的,它的工作原理是。但无论如何,它是处理器的时钟和内存访问(它很容易变成虚拟内存)。 关于带有const指定符的方法。如果你写一个库,你必须始终牢记,对象可能需要一个常量,所以在那些方法中,不改变对象的状态,因为它是可取的。不过到目前为止,就我自己而言,我并没有真正去理会它。 编写你自己的系统,这可能是正确的决定。这只是有趣的前景,在薪酬/劳动比例上还看不到,因此也不会有什么定论,所以只是为了自己的需要)。 1.没有争论,但我要说的是,你不需要CheckPointer(即使是对下家),因为 dynamic_cast不能返回一个非无效的指针,只能返回NULL。 2.这甚至很有趣,但我不能马上想到一个例子,除了在工作时直接杀死动态对象或 "弄脏 "内存之外,还可以得到一个非无效的指针。 我想还是有这样的方法,但它们很可能都在绕过编译器检查的平面上。 3,4 同意。 P.S. 我一定是看错了1-st。测试结果显示,情况恰恰相反。这一定只是一种印象)。 void OnStart() { CChartObjectRectangle *base = new CChartObjectRectangle(); CChartObjectRectangleX *rect = new CChartObjectRectangleX(); CChartObjectRectangle * dbase ; const CChartObjectRectangleX *drect ; Print("dbase= ",dbase, " NULL ? ",dbase==NULL," check? ",!dbase, " broken? ", EnumToString( CheckPointer(dbase) )); dbase=dynamic_cast< CChartObjectRectangle *> (base); Print("dbase= ",dbase, " NULL ? ",dbase==NULL, " check? ",!dbase," broken? ", EnumToString( CheckPointer(dbase) )); delete base; Print("dbase= ",dbase, " NULL ? ",dbase==NULL," check? ",!dbase, " broken? ", EnumToString( CheckPointer(dbase) )); dbase=dynamic_cast< CChartObjectRectangle *> (base); Print("dbase= ",dbase, " NULL ? ",dbase==NULL," check? ",!dbase, " broken? ", EnumToString( CheckPointer(dbase) )); } Pavel Verveyko 2020.06.15 21:11 #829 是否可以在公有类部分声明一个静态数组 并在构造函数中初始化它?(如下图)(或只按元素计算?) bool Mass[5] = { false, true, false, true, true }; Sergey Dzyublik 2020.06.15 21:18 #830 Pavel Verveyko: 静态数组 可以在公有类部分声明并在构造函数中初始化吗?(如下图)(或仅逐个元素?) 你可以初始化一个本地数组并执行ArrayCopy到相应的数组字段。 class A{ public: bool Mass[5]; A(){ bool mass_init[5] = { false, true, false, true, true }; ArrayCopy(Mass, mass_init); } }; 1...767778798081828384858687888990...96 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
呀...人们对const(((())是多么的混乱。
要理解带有const指定符的方法
现在做
//int Get() const {return i;}
然后反之亦然。
// int Get() {return 2*i;}
)))
也是同一代码的一个变体。
这是与常数有关的。
而且你确信,输入的
你会一直喂养
不检查就写?
?
由于基类没有对输入参数的引用,所以没有宪法 的变体也能正确工作,尽管这种风格不是很聪明
这样做是行不通的。你不能改变比较中的签名。这主要是SB中包含的QuickSort方法所需要的,它可以使常规排序工作。
如果你改变签名,它就不是虚函数的覆盖,而是重载,它调用基类CObject 的方法,返回0。
当然,这可以通过对容器的包装(装饰)来解决,但为什么要做这些不必要的动作,否则就不要用SB,一切从头开始写。
它似乎与你的相同,只是字母较少。因此,这是一个品味问题,但我删除了额外的变量(很可能,编译器会将其作为优化的一部分而删除)。
关于我的!节点检查。必须用CheckPointer(node)==POINTER_INVALID来代替, 但这是一个开销--一个函数调用。即使它是内联的,它至少也是在取消引用和检查状态标志。如果只是库或具体的,你写的程序将使用比较方法,最好!节点和代码上的无效指针。如果你懒得注意指针,或者这是一个为弱者准备的库,只有CheckPointer(node)==POINTER_INVALID。
如果你删除了你强调的const指定符,你就不能从一个常量对象 中调用这些方法。
UPD:可以删除突出显示的检查,因为它是在被调用的方法中。
Vladimir,只是在这种情况下CheckPointer是多余的。 dynamic_cast会在任何失败的cast中返回NULL,包括指针被破坏的情况。如果我说错了,请纠正我。很久以前测试过,测试时间为5秒)。
CheckPointer的工作机制(简单的说,我不太懂低级别的术语)--它通过指针寻找什么样的对象,动态的还是静态的,如果我们不能得到信息,就意味着POINTER_INVALID。这可能是在动态对象被删除的情况下,其他情况我不知道,或者上传垃圾到指针,但必须检查编译器,如果你找不到漏洞。
和dynamic_cast做同样的事情,同时检查指针是否可以被投到所需的类型,即它是否是这个类型的指针或子类的指针。
如果指针被破坏,dynamic_cast无法检测到任何东西并返回NULL。
这就是为什么我没有使用CheckPointer。但我通常在任何地方都使用这种检查,以避免受到伤害。毕竟,要在软件中找到一个错误,这是不倒的,似乎有点容易)。
而非const - 理论上我们可以有一个类似GetRatingByAnyFormula()的方法 { m_rating01=Formula01(); return m_rating01;}。
如果不立即用于排序,将相当不方便,也就是说,我们必须先计算评级,然后再调用按评级排序。或者,正如已经说过的,从头开始写你自己的SB)。
这不是好事。签名不能在比较中改变。这主要是为了让SB中包含的常规排序方法QuickSort发挥作用。
如果你改变了签名,就不是对虚函数的覆盖,而是重载,基类CObject 的方法将被调用,其中返回0。
当然,这可以通过对容器的包装(装饰)来解决,但为什么要做这些不必要的动作,或者不使用SB而从头开始写一切?
最正确的方法是不在µl上写字
Vladimir,在这种情况下,CheckPointer是多余的。 dynamic_cast将在任何不成功的投掷中返回NULL,包括指针被破坏的情况。如果我说错了,请纠正我。很久以前测试过,测试时间为5秒)。
CheckPointer的工作机制(简单的说,我不太懂低级别的术语)--它通过指针寻找什么样的对象,动态的还是静态的,如果我们不能得到信息,就意味着POINTER_INVALID。这可能是在动态对象被删除的情况下,其他情况我不知道,或者上传垃圾到指针,但必须检查编译器,如果你找不到漏洞。
和dynamic_cast做同样的事情,同时检查指针是否可以被投到所需的类型,即它是否是这个类型的指针或子类的指针。
如果指针被破坏,dynamic_cast无法检测到任何东西并返回NULL。
这就是为什么我没有使用CheckPointer。但我通常在任何地方都使用这种检查,以避免受到伤害。毕竟,要在软件中找到一个错误,这是不倒的,似乎有点容易)。
而非const - 理论上我们可以有一个类似GetRatingByAnyFormula()的方法 { m_rating01=Formula01(); return m_rating01;}。
如果不立即用于排序,将相当不方便,也就是说,我们必须先计算评级,然后再调用按评级排序。或者你可以像前面提到的那样从头开始写你自己的SB)。
关于我的!节点检查。它应该被CheckPointer(node)==POINTER_INVALID取代,但这是一个开销,函数调用。
问题不在于开销,而在于破损的指针会改变程序的逻辑。 也就是说,你不但没有发现问题,反而会把它埋得更深。
CheckPointer 应该只用于调试目的,或者作为弱指针的实现。
1.没有争论,但我要说的是,你不需要CheckPointer(即使是对下家),因为 dynamic_cast不能返回一个非无效的指针,只能返回NULL。
2.这甚至很有趣,但我不能马上想到一个例子,除了在工作时直接杀死动态对象或 "弄脏 "内存之外,还可以得到一个非无效的指针。
我想还是有这样的方法,但它们很可能都在绕过编译器检查的平面上。
3,4 同意。
P.S.
我一定是看错了1-st。测试结果显示,情况恰恰相反。这一定只是一种印象)。
静态数组 可以在公有类部分声明并在构造函数中初始化吗?(如下图)(或仅逐个元素?)
你可以初始化一个本地数组并执行ArrayCopy到相应的数组字段。