错误、漏洞、问题 - 页 2357

 
Ilya Malev:

谢谢你的详细回答,但是,我有点不明白这个逻辑。

1) 为什么编译器认为B* b1=a结构是对A::A(const A&)复制操作符的调用(而不是对B::B(const A&)的调用,因为它是=操作符左边的B类)?

2)为什么编译器没有产生 "缺少复制构造函数 "的警告?

3)为什么对不存在的对象允许 "简单 "的方法调用(而试图直接调用A::f()会产生编译错误 "不是静态方法 调用")?

1)我写道,这是一个明显的错误,无论如何我们都要修正。

2) 如果用户没有声明,复制构造函数由编译器生成。

3)问题不是很清楚。
从讨论的背景来看。
人们可以争论很久,如果没有对一个指针的访问,是否要 "解除引用 "该指针?
解除引用操作(从句柄中获取实际的指针)是 "内部"(不是自定义)和昂贵的(与没有它相比)代码。
如果没有指针访问,为什么要进行解参考?
只要它保持原样,如果没有指针访问,去引用操作就会被优化器删除。

 
Ilya Malev:

4)为什么编译器允许一个 "简单的 "虚拟方法调用?我认为虚拟性不应该取决于对象中是否有数据。

你把这两者混淆了。

调用 devirtualization 是一种独立的优化方法,与对象中是否存在字段无关。

 
Ilyas:

2)复制构造函数是由编译器生成的,除非由用户声明。

左边有一个B对象,为什么要为它调用(或生成)A::A(A&)构造函数? 这与OOP的原则相矛盾
 
Alexey Navoykov:
左边有对象B,为什么要为它调用构造函数A::A()?

因为在μl中,当左边有一个指针,右边有一个 "对象 "时,运算符=, ==, !=, !&, &|和||总是这样表现。同时,这些操作符不能在指针上重载。

所以,当你修复这个错误时,请让上述操作符对动态对象可重载。

 
Metatrader 4已经停止工作,当我启动时,它工作了一秒钟左右,然后在左上角出现一个一键交易窗口(买/卖),然后应用程序关闭。
有什么建议可以解决这个问题吗?
提前感谢您的帮助。
 
Ilya Malev:

因为当指针在左边,"对象 "类型在右边时,运算符=、==、!=、!&、&&和||在μl中总是这样表现。

指针有什么关系? 我已经在这里 告诉你了。这里的工作方式与没有指针的工作方式相同。
 
Alexey Navoykov:
左边有对象B,为什么要为它调用(或生成)A::A(A&)构造函数? 这与OOP的原则相矛盾

我完全同意你的观点,并且已经写过,这是一个错误,将予以纠正。

在这种情况下,编译器在继承上捡到了一个合适的重载,这不应该在对象的构造上进行。

 
伊利亚斯

人们可以就是否在没有访问权的情况下 "取消引用 "一个指针争论很久。

解除引用操作(从句柄中获得一个真正的指针)是 "内部"(不是自定义)和昂贵的(与没有它相比)代码。
如果没有指针访问,为什么要进行去参考?

因为虚拟方法列表是对象信息的一部分,其重要性不亚于数据本身,而且对虚拟方法的访问是指针式访问。例如,如果我在我的例子中写道

  A* aa=a;
  B* b1=a;   
  b1=aa;
  b1.f();

我将再次得到B::f(),尽管这段代码明确提到了A*对象的赋值,它是从A中 "复制 "出来的,并被A*所引用。这是比调用 "错误的 "复制构造函数更深的情况。但是,即使该对象没有任何虚拟方法,我们仍然应该在访问它的时候检查指针的有效性。

 
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()
而不是别的什么!

 
A100:

你确定那里有什么东西叫什么?我在X32中检查了。

结果:A::A()
而不是别的什么!

因此,我去检查发电机/优化器的转储,以确定我的位置。