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

 
stringo :

모든 것이 맞습니다. 정확한 일치에 우선 순위가 부여됩니다. 와 진짜 맞아

왜 그러한 통일이 필요한가? 잘못 설계된 프로그램 처리 통일

동일한 코드가 C++ 및 MQL에서 동일한 방식으로 작동하려면 통합이 필요합니다. C++에서 이러한 순서는 이유(!)로 인해 만들어집니다(그렇지 않으면 특정 단계에서 모호성이 발생함). 처음에는 C ++ 컴파일러에 비논리성 및/또는 오류가 있다고 생각했지만 이제는 이 접근 방식에 객관적인 이유가 있다고 생각하는 경향이 있습니다. 다음은 X::g가 완전히 일치하지만 Y::g가 여전히 호출된다는 것을 보여주는 MQL의 예입니다. 이는 이전 예 https://www.mql5.com/ru/forum 과 모순되는 C++에서와 같습니다. / 1111/page1223#comment_1074757

 class A {};
class B : public A {};
class C : public B {};
class X {
public :
         virtual int g( C* c1, C* c2 ) { return ( 1 ); } //полное совпадение здесь
         virtual int g( C* c,  B* b )  { return ( 2 ); }
};
class Y : public C { //здесь ошибся, должно быть public : X
public :
         virtual int g( A* a, B* b ) { return ( 3 ); }
};
void OnStart ()
{
        C* c = new C;
        Y* y = new Y;
         Print ( y.g( c, c ));
}

결과: 3

C++에는 "비논리적"이지만 모호하지 않은 순서가 있는 반면 MQL에는 유형이 정확히 일치하는 무작위 순서가 있습니다. 한 경우에는 기본 클래스가 호출되고 다른 경우에는 파생된

 
A100 :

동일한 코드가 C++ 및 MQL에서 동일한 방식으로 작동하려면 통합이 필요합니다. C++에서 이러한 주문은 이유(!) 처음에는 C ++ 컴파일러에 비논리성 및/또는 오류가 있다고 생각했지만 이제는 이 접근 방식에 객관적인 이유가 있다고 생각하는 경향이 있습니다. 다음은 X::g가 완전히 일치하지만 Y::g가 여전히 호출되는 것을 보여주는 MQL의 예입니다. 이는 이전 예와 모순되는 C++에서와 같습니다.

결과: 3

C++에는 "비논리적"이지만 명확한 순서가 있는 반면 MQL에는 임의의 순서가 있습니다. 유형이 정확히 일치하는 경우에는 기본 클래스가 호출되고 다른 경우에는 파생된 클래스가 호출됩니다.

C++의 어떤 구체적인 구현에 대해 이야기하고 있습니까? 이 구현이 C++ 표준을 준수하는 방법. C++ 표준은 오버로드된 함수가 선택되는 순서에 대해 무엇이라고 말합니까?

실제로 귀하가 설명한 기능의 과부하 는 잘못된 설계의 결과입니다.

소스 이식은 신화입니다. 테스트 프로그램만 다른 C++ 환경에서 동일하게 작동합니다. 다른 환경의 실제 프로그램(실제 실용적인 가치가 있는 수천 줄의 코드에 대해 이야기하고 있음)은 최소한 어떤 방식으로든 다르게 작동합니다. 그리고 MQL과 C++의 통합, 시드 펀드 낭비는 말할 것도 없고...

 
A100 :

동일한 코드가 C++ 및 MQL에서 동일한 방식으로 작동하려면 통합이 필요합니다. C++에서 이러한 순서는 이유(!)로 인해 만들어집니다(그렇지 않으면 특정 단계에서 모호성이 발생함). 처음에는 C ++ 컴파일러에 비논리성 및/또는 오류가 있다고 생각했지만 이제는 이 접근 방식에 객관적인 이유가 있다고 생각하는 경향이 있습니다. 다음은 X::g가 완전히 일치하지만 Y::g가 여전히 호출된다는 것을 보여주는 MQL의 예입니다. 이는 이전 예 https://www.mql5.com/ru/forum 과 모순되는 C++에서와 같습니다. / 1111/page1223#comment_1074757

결과: 3

C++에는 "비논리적"이지만 모호하지 않은 순서가 있는 반면 MQL에는 유형이 정확히 일치하는 무작위 순서가 있습니다. 한 경우에는 기본 클래스가 호출되고 다른 경우에는 파생된

이 예제에서 실수를 한 것 같습니다. 클래스 Y가 C가 아니라 X에서 상속하는 경우 동작은 이전 예제와 일치합니다.
 
stringo :

C++ 표준은 오버로드된 함수가 선택되는 순서에 대해 무엇이라고 말합니까?

Stroustrup 인용: "C++에는 기본 클래스 의 가상 함수 유형과 파생 클래스의 재정의 함수 유형 간에 정확한 일치가 필요합니다."

이제 문제를 파악하고 C++의 정확성에 대한 결론에 도달했습니다. 위의 두 예에서 파생 클래스의 g()는 기본 클래스의 g()를 (대체하는 대신) 숨깁니다. 그리고 가상 메커니즘은 대체가 있는 경우에만 활성화되며 대체는 유형의 정확한 일치가 필요합니다(반환 제외). 반환된 유형의 정밀도만 특정 구현에 따라 달라질 수 있습니다.

 
mql5 :
이 예제에서 실수를 한 것 같습니다. 클래스 Y가 C가 아니라 X에서 상속하는 경우 동작은 이전 예제와 일치합니다.

예, 여기에서 실수를 했으므로 C++와 MQL 모두 명확하지만 다른 순서로 대체 및 숨기기를 사용합니다. 대체와 숨김의 차이점에 대한 이전 게시물의 내 주장을 참조하십시오.

숨길 때 C++에서 경고를 표시한다는 사실은 이 순서가 의도적으로 선택되었음을 나타냅니다.

 class A {};
class B : public A {};

class X {
public :
         virtual int g( A* a )
         virtual int f( B* a )
};
class Y : public X {
public :
         virtual int g( A* a ) //подмена  X::g
         virtual int f( A* a ) //сокрытие X::f
};
 
A100 :

예, 여기에서 실수를 했으므로 C++와 MQL 모두 명확하지만 다른 순서로 대체 및 숨기기를 사용합니다. 대체와 숨김의 차이점에 대한 이전 게시물의 내 주장을 참조하십시오.

숨길 때 C++에서 경고를 표시한다는 사실은 이 순서가 의도적으로 선택되었음을 나타냅니다.

MQL 컴파일러는 메서드(함수)를 검색할 때 부모로의 전환을 예를 들어 MS의 C++와 같이 캐스팅으로 간주하지 않습니다.

메시지를 보내주셔서 감사합니다. 논의해 보겠습니다.

 
mql5 :
MQL 컴파일러는 메서드(함수)를 검색할 때 부모로의 전환을 예를 들어 MS의 C++와 같이 캐스팅으로 간주하지 않습니다.

메시지를 보내주셔서 감사합니다. 논의해 보겠습니다.

MS뿐만 아니라 Borland C++ 5.5.1을 사용했습니다.

Stroustrup은 그렇지 않으면 "out of the end of the class object "와 관련된 불쾌한 결과가 발생할 수 있다고 씁니다.

 
A100 :

Stroustrup 인용: "C++에는 기본 클래스 의 가상 함수 유형과 파생 클래스의 재정의 함수 유형 간에 정확한 일치가 필요합니다."

이제 문제를 파악하고 C++의 정확성에 대한 결론에 도달했습니다. 위의 두 예에서 파생 클래스의 g()는 기본 클래스의 g()를 (대체하는 대신) 숨깁니다. 그리고 가상 메커니즘은 대체가 있는 경우에만 활성화되며 대체는 유형의 정확한 일치가 필요합니다(반환 제외). 반환된 유형의 정밀도만 특정 구현에 따라 달라질 수 있습니다.

잠깐, 기다려. 우리는 다른 매개변수로 함수를 오버로딩하는 것에 대해 이야기하고 있습니다.

반면에 가상 함수에는 항상 동일한 유형의 매개변수가 있습니다. 가상 기능은 논의 대상에서 제외됩니다.

 
A100 :

MS뿐만 아니라 Borland C++ 5.5.1을 사용했습니다.

Stroustrup은 그렇지 않으면 "out of the end of the class object "와 관련된 불쾌한 결과가 발생할 수 있다고 씁니다.

우리는 "양날의 검"인 MQL 컴파일러의 동작을 변경하지 않을 것이라고 논의했습니다. 설명하겠습니다.

문제는 완성된 클래스(작업 프로그램)를 변경할 때만 관련이 있습니다.
부모가 더 적합한 기능을 갖게 된 후 프로그램이 갑자기 작동을 멈춥니다. 자식 메서드 대신 부모 메서드가 호출되었습니다.
글쎄, MQL의 동작을 변경하면 비슷한 상황이 발생할 수 있습니다. 새 메서드가 자식에 추가되면 부모 함수(매개변수 캐스팅 없이) 대신 자식 메서드가 호출되기 시작하고 프로그램이 중지됩니다. 매개변수 캐스팅으로 다시 작업합니다.

따라서 C++과의 호환성 외에 다른 문제는 해결되지 않으며 컴파일러 동작의 변경은 기존 MQL 프로그램에 영향을 미칩니다.
 

Так как переменные типа структур и простых типов не имеют указателей, то применять к ним функцию GetPointer() запрещено.

포인터 를 함수 인수로 전달하는 것도 금지됩니다( ??? GetPointer 또는 전혀? ) . 위의 모든 경우에 컴파일러는 오류를 보고합니다 .

문서에서 인용.

 class A{
public :
   void operator = ( const A* from){
       if ( GetPointer ( this ) == GetPointer (from))      // а тут я передаю и все ок
         Alert ( 1 );                                  // резутат 1  из за того что передаю this
       else
         Alert ( 2 );
   }
};

class B : public A{
public :
   void operator = ( const B& from){  
       if ( GetPointer ( this ) == GetPointer (from))
         return ;
       operator =((A*)( GetPointer ( this )));
   }
};
  B b;
   B bb;                        // забыл написать создание объектов и вызов функции.
   b = bb;

왜 맹세하지??? 나는 이미 경고를 이해했습니다. 기능으로 전달하지 않은 것에 대해 나 자신이 책임이 있습니다.