错误、漏洞、问题 - 页 2357 1...235023512352235323542355235623572358235923602361236223632364...3184 新评论 Ilyas 2018.12.24 14:32 #23561 Ilya Malev:谢谢你的详细回答,但是,我有点不明白这个逻辑。 1) 为什么编译器认为B* b1=a结构是对A::A(const A&)复制操作符的调用(而不是对B::B(const A&)的调用,因为它是=操作符左边的B类)? 2)为什么编译器没有产生 "缺少复制构造函数 "的警告? 3)为什么对不存在的对象允许 "简单 "的方法调用(而试图直接调用A::f()会产生编译错误 "不是静态方法 调用")?1)我写道,这是一个明显的错误,无论如何我们都要修正。 2) 如果用户没有声明,复制构造函数由编译器生成。 3)问题不是很清楚。 从讨论的背景来看。 人们可以争论很久,如果没有对一个指针的访问,是否要 "解除引用 "该指针? 解除引用操作(从句柄中获取实际的指针)是 "内部"(不是自定义)和昂贵的(与没有它相比)代码。 如果没有指针访问,为什么要进行解参考? 只要它保持原样,如果没有指针访问,去引用操作就会被优化器删除。 Ilyas 2018.12.24 14:35 #23562 Ilya Malev:4)为什么编译器允许一个 "简单的 "虚拟方法调用?我认为虚拟性不应该取决于对象中是否有数据。你把这两者混淆了。 调用 devirtualization 是一种独立的优化方法,与对象中是否存在字段无关。 Alexey Navoykov 2018.12.24 14:44 #23563 Ilyas: 2)复制构造函数是由编译器生成的,除非由用户声明。 左边有一个B对象,为什么要为它调用(或生成)A::A(A&)构造函数? 这与OOP的原则相矛盾 Ilya Malev 2018.12.24 14:47 #23564 Alexey Navoykov: 左边有对象B,为什么要为它调用构造函数A::A()?因为在μl中,当左边有一个指针,右边有一个 "对象 "时,运算符=, ==, !=, !&, &|和||总是这样表现。同时,这些操作符不能在指针上重载。 所以,当你修复这个错误时,请让上述操作符对动态对象可重载。 Dima Tutov 2018.12.24 14:47 #23565 Metatrader 4已经停止工作,当我启动时,它工作了一秒钟左右,然后在左上角出现一个一键交易窗口(买/卖),然后应用程序关闭。 有什么建议可以解决这个问题吗? 提前感谢您的帮助。 Alexey Navoykov 2018.12.24 14:51 #23566 Ilya Malev:因为当指针在左边,"对象 "类型在右边时,运算符=、==、!=、!&、&&和||在μl中总是这样表现。 指针有什么关系? 我已经在这里 告诉你了。这里的工作方式与没有指针的工作方式相同。 Ilyas 2018.12.24 14:55 #23567 Alexey Navoykov: 左边有对象B,为什么要为它调用(或生成)A::A(A&)构造函数? 这与OOP的原则相矛盾我完全同意你的观点,并且已经写过,这是一个错误,将予以纠正。 在这种情况下,编译器在继承上捡到了一个合适的重载,这不应该在对象的构造上进行。 Ilya Malev 2018.12.24 14:56 #23568 伊利亚斯。人们可以就是否在没有访问权的情况下 "取消引用 "一个指针争论很久。解除引用操作(从句柄中获得一个真正的指针)是 "内部"(不是自定义)和昂贵的(与没有它相比)代码。 如果没有指针访问,为什么要进行去参考? 因为虚拟方法列表是对象信息的一部分,其重要性不亚于数据本身,而且对虚拟方法的访问是指针式访问。例如,如果我在我的例子中写道 A* aa=a; B* b1=a; b1=aa; b1.f(); 我将再次得到B::f(),尽管这段代码明确提到了A*对象的赋值,它是从A中 "复制 "出来的,并被A*所引用。这是比调用 "错误的 "复制构造函数更深的情况。但是,即使该对象没有任何虚拟方法,我们仍然应该在访问它的时候检查指针的有效性。 A100 2018.12.24 14:57 #23569 Alexey Navoykov: 左边有一个B对象,为什么要为它调用(或生成)A::A(A&)构造函数? 这与OOP的原则相矛盾。你确定那里有什么东西叫什么?我在X32中检查了。 class A { public: A() { Print(__FUNCSIG__); } A( const A& ) { Print(__FUNCSIG__); } } a; class B : public A { public: B() { Print(__FUNCSIG__); } B( const B& ) { Print(__FUNCSIG__); } } *b = a; void OnStart() {} 结果:A::A() 而不是别的什么! Ilyas 2018.12.24 15:04 #23570 A100:你确定那里有什么东西叫什么?我在X32中检查了。 结果:A::A() 而不是别的什么!因此,我去检查发电机/优化器的转储,以确定我的位置。 1...235023512352235323542355235623572358235923602361236223632364...3184 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
谢谢你的详细回答,但是,我有点不明白这个逻辑。
1) 为什么编译器认为B* b1=a结构是对A::A(const A&)复制操作符的调用(而不是对B::B(const A&)的调用,因为它是=操作符左边的B类)?
2)为什么编译器没有产生 "缺少复制构造函数 "的警告?
3)为什么对不存在的对象允许 "简单 "的方法调用(而试图直接调用A::f()会产生编译错误 "不是静态方法 调用")?
1)我写道,这是一个明显的错误,无论如何我们都要修正。
2) 如果用户没有声明,复制构造函数由编译器生成。
3)问题不是很清楚。
从讨论的背景来看。
人们可以争论很久,如果没有对一个指针的访问,是否要 "解除引用 "该指针?
解除引用操作(从句柄中获取实际的指针)是 "内部"(不是自定义)和昂贵的(与没有它相比)代码。
如果没有指针访问,为什么要进行解参考?
只要它保持原样,如果没有指针访问,去引用操作就会被优化器删除。
4)为什么编译器允许一个 "简单的 "虚拟方法调用?我认为虚拟性不应该取决于对象中是否有数据。
你把这两者混淆了。
调用 devirtualization 是一种独立的优化方法,与对象中是否存在字段无关。
2)复制构造函数是由编译器生成的,除非由用户声明。
左边有对象B,为什么要为它调用构造函数A::A()?
因为在μl中,当左边有一个指针,右边有一个 "对象 "时,运算符=, ==, !=, !&, &|和||总是这样表现。同时,这些操作符不能在指针上重载。
所以,当你修复这个错误时,请让上述操作符对动态对象可重载。
有什么建议可以解决这个问题吗?
提前感谢您的帮助。
因为当指针在左边,"对象 "类型在右边时,运算符=、==、!=、!&、&&和||在μl中总是这样表现。
左边有对象B,为什么要为它调用(或生成)A::A(A&)构造函数? 这与OOP的原则相矛盾
我完全同意你的观点,并且已经写过,这是一个错误,将予以纠正。
在这种情况下,编译器在继承上捡到了一个合适的重载,这不应该在对象的构造上进行。
人们可以就是否在没有访问权的情况下 "取消引用 "一个指针争论很久。
解除引用操作(从句柄中获得一个真正的指针)是 "内部"(不是自定义)和昂贵的(与没有它相比)代码。
如果没有指针访问,为什么要进行去参考?
因为虚拟方法列表是对象信息的一部分,其重要性不亚于数据本身,而且对虚拟方法的访问是指针式访问。例如,如果我在我的例子中写道
我将再次得到B::f(),尽管这段代码明确提到了A*对象的赋值,它是从A中 "复制 "出来的,并被A*所引用。这是比调用 "错误的 "复制构造函数更深的情况。但是,即使该对象没有任何虚拟方法,我们仍然应该在访问它的时候检查指针的有效性。
左边有一个B对象,为什么要为它调用(或生成)A::A(A&)构造函数? 这与OOP的原则相矛盾。
你确定那里有什么东西叫什么?我在X32中检查了。
结果:A::A()
而不是别的什么!
你确定那里有什么东西叫什么?我在X32中检查了。
结果:A::A()
而不是别的什么!
因此,我去检查发电机/优化器的转储,以确定我的位置。