오류, 버그, 질문 - 페이지 1183

 
Zeleniy :

Advisor를 테스트 할 때 오류가 발생합니다.

OrderSend 기능에 대한 잘못된 이익 창출

주문 보내기 오류 4107

어드바이저 코드에 들어가지 않고 어떻게 고칠 수 있습니까?

설정에서 이익실현을 늘리거나 줄이십시오.
 
mql5 :
이 개체에 대해 ZeroMemory 기능을 사용할 수 없습니다.

알았습니다. 그런데 왜 컴파일러는 ZeroMemory 가 사용되는 곳이 아니라 클래스가 선언된 곳에서 이 오류를 표시할까요? 혼란스럽다. 나는 이미 오류가 무엇인지, 오류가 어디에 있는지 이해하려고 노력하면서 머리를 완전히 깨뜨 렸습니다. 오류가 올바른 위치에서 발생했는지 확인하십시오. 결국, 예를 들어 복사가 허용되지 않는 요소가 포함된 객체를 복사할 때 오류는 클래스 내부가 아니라 복사하는 라인에서 정확하게 발생합니다.

 
meat :

이 모든 것의 실용적인 측면으로 이동하면 이미 문제에 직면해야 했습니다. 코드는 정적 개체를 사용했습니다. 그런 다음 나는 그들 중 일부를 동적 인 것으로 교체하기로 결정했습니다. 결과적으로 비교 및 할당 작업이 완전히 다르게 작동하기 시작했습니다. 그리고 이 문제는 식별하기 어려웠습니다. 프로그램은 계속해서 정상적으로 컴파일되고 실행되지만 정상적으로 실행되지 않습니다.

나는 문제의 본질을 즉시 이해하지 못했다

 class B {};

class A {
public :
         bool operator !=( A* a ) { Print ( __FUNCTION__ ); return ( true   );  }
         bool operator !=( B* b ) { Print ( __FUNCTION__ ); return ( false );  }
         bool operator >>( A* a ) { Print ( __FUNCTION__ ); return ( true   );  }
         bool operator +( A* a )  { Print ( __FUNCTION__ ); return ( false   ); }
         bool operator !()        { Print ( __FUNCTION__ ); return ( true    ); }
};

void OnStart ()
{
        A *a = new A;
        B *b = new B;
         if ( a != a ) Print ( "1" );
         if ( a != b ) Print ( "2" );
         if ( a >> a ) Print ( "3" );
         if ( !a )     Print ( "4" );
         delete ( a );
         delete ( b );
}
이것은 (a != a)가 포인터 비교를 초래하는 반면 (a >> a)는 연산자 >>( A* )에 대한 호출을 초래한다는 것을 보여줍니다.

모순이 있다.

다른 오버로드된 연산자(== 및 != 제외)처럼 (a >> a)의 동작을 변경할 수 없습니다. 왜냐하면 (A)는 반환될 수 없지만 (A*)만 반환될 수 있기 때문에 다음 구성이 불가능하기 때문입니다. 돌아왔다.

 class A {
public :
        A * operator >>( string str ) { return ( GetPointer ( this ) ); }
};

void OnStart ()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили" ; //множественное применение оператора <<
}

또한 객체(*a)에 대한 포인터 캐스트 작업이 없기 때문에 오버로드된 연산자를 완전히 사용하는 것도 불가능합니다.

동작(== 및 !=)을 변경하는 것만 남아 있습니다.

포인터(== 및 !=)를 서로 그리고 숫자 \0과 비교하려면(포인터를 사용한 다른 연산은 의미가 없기 때문에) (GetPointer)와 같은 특수 함수를 도입하거나 컴파일러에 명시적으로 캐스트 하도록 지시해야 합니다.

 void OnStart ()
{
        A *a = new A;
        B *b = new B;
         if ( ulong (a) != ulong (b) ) Print ( "2" ); //хочу сравнить указатели
         if (       a  !=       b  ) Print ( "2" ); //хочу вызвать operator != ( B* )

}

따라서 과부하 연산자를 완전히 사용할 가능성은 남아 있고 위의 모순이 제거됩니다.

일반 규칙에 대한 유일한 합리적인 예외는 operator=()여야 합니다.


class A {
public :
        A * operator =( A* a ) { return ( GetPointer ( this ) ); }
};
void OnStart ()
{
        A *a = new A;
        a = a; //не должно трактоваться компилятором как вызов operator=( A* ),
                // а должно остаться как присваивание указателю значения
}
 
그리고 물론 연산자에 대해 (*a)를 사용하라는 제안은 C++에서 허용되는 표기법으로 돌아가는 것입니다.
 class A {
public :
         bool operator !=( A* a ) { Print ( __FUNCTION__ ); return ( true   );  }
};

void OnStart ()
{
        A *a = new A;
         if (  a !=  a ) Print ( 1 ); //сравнение указателей
         if ( *a != *a ) Print ( 2 ); //вызов operator !=( A* )
}

즉시 모든 모순을 제거합니다.

스스로 수정하겠습니다. 사실, 이러한 표기법(*a)은 연산자의 다중 적용 문제를 해결하지 못하기 때문에 모순은 부분적으로만 제거됩니다(이제는 == 및 !=를 제외한 모든 연산자에서 성공적으로 작동함) - 따라서 포인터를 서로 비교하는 가장 좋은 방법은 같음\비등등성이 특수 함수를 사용하여 유지되는 것입니다. 또는 ulong 유형 에 대한 명시적 캐스트

 
A100, 메시지 감사합니다. 해결하겠습니다.
 
컴파일 오류
 class A {
public :
      A( int a1 ) : a3( a1 ) { }
  static int a2;
         int a3;
};
int A::a2 = 1 ;

void OnStart ()
{
         int b = A::a2;   //нормально
        A t1( b );     //нормально
        A t2( A::a2 ); //ошибка компиляции
        A* t3 = new A( A::a2 ); //нормально
}
정적 멤버 생성자 인수(새 항목 제외)인 경우
 
컴파일러는 래핑 후 #define 내부에 주석 달기를 허용하지 않습니다.
 #define f( x )                   \
        ( x != 0 &&   /*comment*/ \ 
          x != 1 )

너무 좋아 그래서

 #define f( x )       \
        ( x != 0 &&  \ /*comment*/
          x != 1 )
컴파일 오류
 

포인터에 대한 주제를 계속해서 MQL에 표준 ' & ' 포인터 취하는 연산자를 추가하면 성가신 GetPointer보다 훨씬 더 편리하고 컴팩트할 것입니다. 그리고 위에서 논의한 것처럼 ulong을 사용하여 캐스팅할 필요가 없습니다. 따라서 무기고에 *& 연산자가 있으면 필요한 작업을 고유하게 결정할 수 있습니다.

 if (&a==&b) Print ( "Указатели равны" );
if (*a==*b) Print ( "Объекты равны" );


이 앰퍼샌드에 대해 자세히 알아보세요. MQL 에는 변수에 대한 참조 가 거의 없습니다. 특히 포인터의 제한된 사용을 고려합니다(클래스 객체에만 해당). 구조체나 다차원 배열 의 깊게 중첩된 요소에 액세스해야 하는 경우가 많습니다. 매번 전체 경로를 작성해야 하므로 코드가 많이 복잡해집니다. 링크를 생성하면 모든 것을 단순화할 수 있습니다. 그리고 일반적으로 편의를 위해 일부 변수의 이름을 로컬에서 "변경"해야 할 수도 있습니다. 그러나 내가 여기서 설명하는 것은. 링크 사용의 편리함은 이미 모든 사람에게 알려져 있습니다. 이제 대신 #define을 사용해야 합니다. 물론 이는 매우 좋지 않습니다.

음, 참조로 함수의 결과를 전달하는 기능도 필요합니다. 이중 Func() { }

 

최근 Facebook의 블로그에서 중복 게시물이 발생했습니다.

하나

 
meat :

포인터에 대한 주제를 계속해서 MQL에 표준 ' & ' 포인터 취하는 연산자를 추가하면 성가신 GetPointer보다 훨씬 더 편리하고 컴팩트할 것입니다. 그리고 위에서 논의한 것처럼 ulong을 사용하여 캐스팅할 필요가 없습니다. 따라서 무기고에 *& 연산자가 있으면 필요한 작업을 고유하게 결정할 수 있습니다.

(*a)를 통해서만 멤버 함수에 대한 액세스를 허용하면 명백한 이점이 없지만 반대로 간단하고 이해하기 쉬운 연산자의 다중 적용이 불가능하게 됩니다.

 class A {
public :
        A * operator >>( string str ) { Print ( __FUNCTION__ ); return ( GetPointer ( this ) ); }
};

void OnStart ()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили" ; //простая и понятная запись

당신의 제안에 따라 그것을 다시 쓰십시오

 void OnStart ()
{
        A *a = new A;
        *(*(*(*a << "1234" ) << "мы" ) << "всю ночь" ) << "тусили" ; //запутанная запись
}

연산자 <<(...)는 개체에 대한 포인터만 반환할 수 있기 때문에 포인터 대신 개체 자체를 사용할 수 없습니다.

포인터를 사용한 작업이 의미가 없는 것은 무엇입니까? - 자신과 숫자 사이의 비교만 - 따라서 연산자 없이 연산자를 여러 번 사용할 수 있는 가능성을 유지하기 위해 특수 함수(예: bool ComparePointer( a, b))를 제공하여 무시해야 합니다. 과부하 자체는 주요 의미를 잃습니다.