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

 
SemenTalonov:

中奖了!

SemenTalonov2019.01.10 07:36POINTER_AUTOMATIC 类型的指针,反之亦然

这不完全是一个宾果。对于简单的对象,用运算符=进行赋值是可行的。这不是一个错误,是肯定的。

 
SemenTalonov:

...

SemenTalonov2019.01.10 07:36POINTER_AUTOMATIC 类型的指针保存到一个POINTER_DYNAMIC 类型 的指针,反之亦然

不,当它不是自动分配一个指针时,它是复制一个对象--它的字段的值,但只限于简单的对象。

 

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

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

塞门-塔洛诺夫, 2019.01.10 04:18

class A
{
public:
    int iValue;
};
//......................
A m_A[2];

void OnStart()
{
A a;

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


从什么时候开始,他们被定义了(对开发者的问题)。

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

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

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


而这里的情况并不清楚

A* m_A[2];

void OnStart()
{
A a;

    m_A[0] =a;  // Почему это работает?
    m_A[0] =&a; // Когда должно работать только это?
}
 
Dmitry Fedoseev:

不完全是一个宾果。对于简单的对象,用运算符=进行赋值是可行的。可以肯定的是,这不是一个错误。

这就对了,这是最重要的一点。

我个人认为,如果没有明确定义这个运算符,就不能对对象使用赋值运算符,即使对象很简单。我们仍然可以在某种程度上同意简单结构的分配。但是那些构造函数必须被调用(至少是隐含的)的类--只能通过明确定义的操作符来进行分配。

在我看来,这样做是为了让新手们的生活更容易。

 
Georgiy Merts:

这是正确的,这是最重要的一点。

我个人认为,如果赋值 运算符没有明确定义,你就不能对对象使用赋值运算符,即使对象是简单的。我们可以在某种程度上同意简单结构 的分配。但是那些必须调用构造函数的类(至少是隐式的)--只能用明确定义的操作符来分配。

在我看来,这样做是为了让初学者的生活更轻松。

而复杂的则很方便--例如,没有它,你就不能返回MqlTradeRequest。而在结构中,也必然会调用一个构造函数。

 

有一种理论认为,MQL是一种非常精简的C#。所以可以理解MQL编译器在这种情况下的表现。毕竟,C#中的类总是被放在堆中,因此。

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
class A
{
public:
    int iValue;
};
//......................
A m_A[2];

void OnStart()
{
    // Разместили A в куче, указатель на A передали в m_A[1]
    m_A[1] = new A();
    // Разместили A на стеке...
    A a;
    // А вот фиг вам! ля-ля-ля;) Там вам не тут. 'a' - класс и размещается в куче. Указатель на него передается внутреннему сборщику мусора
    // А раз так, то теперь он AUTOMATIC и к нему нельзя применить delete, т.к. внутренний сборщик мусора его удалит сам 
    
    // скопировали указатель a в массив
    m_A[0] = a;
}
//+------------------------------------------------------------------+

现在我们来处理一下m_A数组。因为m_A是一个类的数组,而类总是放在堆中,所以没有必要指定数组m_A是指针数组还是对象本身的数组,因为只有第一个变体总是对类有效。由于m_A总是一个指针数组,MQL不必指定它是存储引用类型还是显著类型。因此,A* m_A[2] == A m_A[2]。阿门。

 
Vasiliy Sokolov:

有一种理论认为,MQL是一种非常精简的C#。所以可以理解MQL编译器在这种情况下的表现。毕竟,C#中的类总是被放在堆中,因此。

现在我们来处理一下m_A数组。因为m_A是一个类的数组,而类总是放在堆中,所以没有必要指定数组m_A是指针数组还是对象本身的数组,因为只有第一个变体总是对类有效。由于m_A总是一个指针数组,MQL不必指定它是存储引用类型还是显著类型。因此,A* m_A[2] == A m_A[2]。阿门。

不正确的结论。m_A是一个对象的数组,不是指针。而这些物体被完全摧毁。被破坏的不是新A。

class A
{
public:
    int iValue;
    
  ~A()
  {
    Print(__FUNCSIG__);
  }
};
//......................
A m_A[2];

void OnStart()
{
A a;
A* b = new A;

    m_A[0] =a;  // копирование объекта, а не указателя
    m_A[1] = b; // копирование объекта, а не указателя
    
  // по выходу уничтожится три объекта
  delete b; // а так - четыре.
}
 
fxsaber:

不正确的输出。m_A是一个对象的数组,不是指针。而这些物体被完全摧毁。被破坏的不是新A。

这是个好例子。好吧,那我们就继续思考一下吧。

 

Pfft))我对此感到震惊。

A m_A[2];

void OnStart()
{
A a;
A* b = new A();

    printf("SizeOf 'a' object: %i SizeOf pointer 'b' to object: %i", sizeof(a), sizeof(b));
    
    a =b;
    b =a;
    
    m_A[0] = a;
    m_A[1] = b;
}
SizeOf 'a' object: 20 SizeOf pointer to 'b' object: 8
 
SemenTalonov:

呼))其实我对此感到很震惊。

它有什么问题?一种情况是一个对象,另一种情况是一个指针。