MQL5 컴파일러는 클래스와 이에 대한 포인터를 구분하지 않습니다. - 페이지 3

 
SemenTalonov :

빙고!

정액Talonov 2019.01.10 07:36 POINTER_DYNAMIC 유형의 포인터를 저장할 수 있으며 그 반대 의 경우도 마찬가지입니다.

정확히는 빙고가 아닙니다. 단순 개체의 경우 = 연산자를 사용한 할당이 작동합니다. 확실히 버그는 아닙니다.

 
SemenTalonov :

...

정액탈로 노프 2019.01.10 07:36 POINTER_DYNAMIC 유형의 포인터를 저장할 수 있으며 그 반대 의 경우도 마찬가지입니다.

아니요. 스피커의 자동에서 이것은 포인터가 할당되지 않지만 개체가 복사됩니다. 해당 필드의 값은 단순 개체에만 해당됩니다.

 

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

MQL5 컴파일러는 클래스와 이에 대한 포인터를 구분하지 않습니다.

SemenTalonov , 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는 파괴되지 않습니다.

좋은 예입니다. 흠. 그러면 우리는 더 생각할 것입니다.

 

하하)) 나는 사실 이것에 충격을 받았다.

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 :

하하)) 나는 사실 이것에 충격을 받았다.

그리고 무엇이 잘못되었나요? 한 경우에는 객체이고 다른 경우에는 포인터입니다.

사유: