MQL5 编译器不区分类和它的指针 - 页 5

 
=号将一个对象的内存区域复制到另一个对象的内存区域。所有物体都保持原来的位置。
 
Vladimir Simakov:
没有办法触发它。这纯粹是内存泄漏。

让它可以被召唤。

 

顺便说一句,各位开发者,我们最好能解决这个问题。毕竟new确实返回了一个指针,所以添加一个检查,在另一端=也是一个指针,删除隐含的转换(A) new A(); 按照我的理解--这就是发生的事情。

 
Vladimir Simakov:

顺便说一句,亲爱的开发者,我最好能解决这个问题。毕竟new真正返回的是一个指针,所以增加一个检查,即另一端=也是一个指针,去掉隐含的转换(A) new A(); 按照我的理解--这就是发生的事情。

有一个关于这个操作员的电话

关于交易、自动交易系统和策略测试的论坛

MQL5编译器不区分类和指针的区别

fxsaber, 2019.01.10 06:36

这些是什么时候定义的(给开发者的问题)?

void A::operator =( const A& );
void A::operator =( const A* );

它们又是如何工作的呢?下面的编译代码看起来是妄想

    A* b = NULL;    
    m_A[1] = b;    


粗略地说,它看起来像这样

class A
{
public:
    int iValue;
    
    void operator =( const A* Ptr )
    {
      Print(__FUNCSIG__);
      
      this.iValue = Ptr.iValue;
    }
};
//......................
A m_A[2];

void OnStart()
{
A a;

    m_A[0] =a; 
    m_A[1] = new A();
}
 
fxsaber:

对该运营商的呼叫就在那里


粗略地说,它看起来像这样

是的,我明白。这是个不错的耙子。顺便说一下,这个操作符重载=在C++中并不存在,VS发誓说。
 

在大惊小怪之前,最好知道在MQL中,指针一直被隐式地投向对象(取消引用),这很方便,大家都习惯了。你可以用通常的OOP格式来写:a().b().c().d(),而不是难以阅读的a()->b()->c()->d( ),在传递给函数的过程中减少不必要的转换。 而现在因为某人的不满,你就改变一切?

 
Alexey Navoykov:

在你大惊小怪之前,最好知道在MQL中,他们所有的指针都被隐式地投给了对象(取消引用),这很方便,而且大家都习惯了。你可以用通常的OOP格式来写:a().b().c().d(),而不是难以阅读的a()->b()->c()->d( ),并且在传递给函数时减少不必要的转换。 而现在因为某人的不满,你就改变一切?

这不是关于铸造。你没有进入它。

 

如果我们以MQL的声明原型为指导--C++。

在C++中,如果m_A是一个对象的数组,new操作符 分别返回一个指针。

m_A[1] = new A();

这里会有一个类型错误。

这是编译器会跳过的那一行。

m_A[1] = *( new A() );

但这将导致内存泄漏。


如果MQL有同样的行为就好了。

 
Alexey Navoykov:

在你开始大惊小怪之前,你应该知道,在MQL中,指针一直被隐式地投向对象(取消引用),这很方便,大家都习惯了。你可以用通常的OOP格式来写:a().b().c().d(),而不是难以阅读的a()->b()->c()->d( ),在传递给函数的过程中减少不必要的转换。 而现在因为某人的不满,你就改变一切?

而如果你用一些简单的例子去详细说明。

A a;

// 'a' ожидает объект
 
a = new A(); // а ему дают указатель, ведь можно же

// что в MQL равнозначно?
a = *(A*) new A();

因此,我们有

1.a'得到所创建对象的 副本,创建的新对象的指针会丢失。

2.如果new不能创建/内存分配一个对象,'a'会发生什么?

第二种情况(相反)是

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)
a = &b;

1.退出函数后,'b'对象必须作为一个本地对象被销毁。

那么 "A "指的是什么?

2.还是复制运算符仍然有效,'b'将被'a'指针复制?

 
SemenTalonov:

第二种情况(相反)是

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)


这里是反过来的--一个指针a 被隐式地投给一个对象(取消引用),然后将operator=应用于它。 fxsaber昨天也提到了这一点。

虽然在逻辑上它与MQL规则不矛盾(因为调用operator=等同于调用任何其他对象方法),但它导致了对这种代码的模糊理解和难以发现的错误。这不仅涉及到operator=,而且还涉及到==和!=。 也许这样的铸造也应该被禁止用于其他运算符,因为在C++中你可以应用到运算符:+-<>[]。

简短的结论是:当在C++中对一个指针应用允许的操作符时,不允许将这个指针隐含地转换为一个对象。 相应地,上面的例子会引起一个编译错误