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

 
Ilya Malev :

MKL에서 모든 것이 분명히 C ++에서와 같지 않다는 것입니다. 여기서 포인터는 별도의 데이터 유형 이 아니므로 둘 다 객체이고 핸들이 변수에 있습니다.

그래서?

 // тот же класс А что был выше

A a; // будет создан автообъект с реальным выделением памяти и инициализацией. 'a' является указателем со статусом POINTER_AUTOMATIC

A* pA; // память под объект не выделена, объекта нет. pA является указателем со статусом POINTER_INVALID или POINTER_DYNAMIC?

POINTER_INVALID 또는 POINTER_DYNAMIC 생성 후 포인터가 받게 될 상태는 다음과 같습니다. 논쟁하지 않겠습니다. 이론적으로 new 에서 주소를 받을 때까지는 POINTER_INVALID여야 합니다.

 
Ilya Malev :

즉, 선언

그리고 당신은 정확히 동일한 "자동 개체"를 갖게 될 것이며, 당신 자신만이 그것을 삭제할 것입니다.

이젠 차가 아니다 ..

 
SemenTalonov :

POINTER_INVALID 또는 POINTER_DYNAMIC 생성 후 포인터가 받게 될 상태는 다음과 같습니다. 논쟁하지 않겠습니다. 이론적으로 new 에서 주소를 받을 때까지는 POINTER_INVALID여야 합니다.

모든 것이 정확하고 상태는 POINTER_INVALID 가 됩니다. 그러나 변수와 pA는 같은 유형입니다. a는 상수이고 생성자는 생성 시 호출되고 소멸자는 블록에서 나갈 때 호출되는 반면 pA는 임의 액세스가 가능하며 생성자와 소멸자의 임의 호출이 있습니다.

* 없이 선언된 변수는 특별한 트릭 없이 POINTER_INVALID 상태를 제공할 수 없습니다. 이것은 또한 사실이지만 변수의 유형이 다르기 때문이 아니라 컴파일러가 생성자와 소멸자 호출을 잘 제어하고 다른 값을 할당하는 것을 금지하기 때문입니다.

그리고 변수의 타입이 같기 때문에 사실 클래스 메소드에 접근하는 방식이 다를 수 밖에 없습니다.

 
Ilya Malev :

모든 것이 정확하고 상태는 POINTER_INVALID 가 됩니다. 그러나 변수와 pA는 같은 유형입니다. a는 상수이고 생성자는 생성 시 호출되고 소멸자는 블록에서 나갈 때 호출되는 반면 pA는 임의 액세스가 가능하며 생성자와 소멸자의 임의 호출이 있습니다.

따라서 모든 붕소 치즈는 구별해야 한다는 사실에서 비롯됩니다. 저것들. 포인터에는 보다 책임감 있는 태도가 필요합니다( DYNAMIC ).

 
SemenTalonov :

따라서 모든 붕소 치즈는 구별해야 한다는 사실에서 비롯됩니다. 저것들. 포인터에는 보다 책임감 있는 태도가 필요합니다( DYNAMIC ).

제 생각에는 OOP의 의미는 객체에 대한 참조를 전달하고 저장할 수 있으며 다른 동작을 가진 다른 클래스를 작성할 수 있다는 것입니다. 다형성 을 건드리지 않고 "auto-object"에 대한 참조를 저장하기 시작하면 이미 모든 구분을 잃게 됩니다(A&와 같은 사용자 정의 변수가 없기 때문에).

 
Ilya Malev :

* 없이 선언된 변수는 특별한 트릭 없이 POINTER_INVALID 상태를 제공할 수 없습니다. 이것은 또한 사실이지만 변수의 유형이 다르기 때문이 아니라 컴파일러가 생성자와 소멸자 호출을 잘 제어하고 다른 값을 할당하는 것을 금지하기 때문입니다.

정확히. 자동 개체 포인터는 상태를 변경 하지 않으며 POINTER_DYNAMIC 포인터는 프로그램 작동 중에 쉽게 무효화될 수 있습니다. 그 이유는 그러한 사건의 가능성만큼 중요하지 않습니다.

 
SemenTalonov :

정확히. 자동 개체 포인터는 상태를 변경 하지 않으며 POINTER_DYNAMIC 포인터는 프로그램 작동 중에 쉽게 무효화될 수 있습니다. 그 이유는 그러한 사건의 가능성만큼 중요하지 않습니다.

이에 대한 훌륭하고 문제 없는 치료법이 있습니다.

 class A{~A(){}};

void OnStart ()
 {
  A*a= new A;
   delete a; // oops =))
 };
뭐, 일반적으로 프로그래머 자신이 객체의 수명과 변수 접근 방식을 모니터링해야 하고, 처음부터 생각한 아키텍처가 코드를 작성한 후 최소 1~2년은 오류를 최소화할 것이라고 생각합니다.
 
사실, 개체의 수명은 개체에 대한 "라이브" 포인터의 수명과 일치해야 합니다. POINTER_DYNAMIC 유형의 동적 개체는 물론 잘못된 코딩으로 문제를 일으키는 무심코 솔루션이기도 합니다. 그러나 POINTER_AUTOMATIC 은 일반적인 개체 작업에 필요한 확장성 수준을 제공하지 않습니다. 이것이 필요합니다. 생성된 자동 변수를 제외하고 블록을 종료할 때 객체에 대한 포인터가 생성되지 않은 경우 객체를 삭제합니다. 현재 블록 외부의 링크가 수신된 경우 이러한 링크가 살아있는 동안 개체를 삭제하지 마십시오. 그러면 확장성이 나타나고 인코더는 삭제를 지속적으로 모니터링할 필요가 없습니다...(예를 들어, 이제 A* a = new A를 작성하고 a = new를 작성하면 첫 번째 개체가 영원히 손실됩니다. , 그리고 프로그램을 종료하면 분명히 로그에 메모리 누수 오류가있을 것입니다. 그러나 자랑스러운 코드 최적화 프로그램은이 시간을 어디에서보고 있습니까?)
 
Ilya Malev :
사실, 개체의 수명은 개체에 대한 "라이브" 포인터의 수명과 일치해야 합니다. POINTER_DYNAMIC 유형의 동적 개체는 물론 잘못된 코딩으로 문제를 일으키는 무심코 솔루션이기도 합니다. 그러나 POINTER_AUTOMATIC 은 일반적인 개체 작업에 필요한 확장성 수준을 제공하지 않습니다. 이것이 필요합니다. 블록에서 나갈 때 객체가 생성된 자동 변수를 제외하고 객체에 대한 포인터가 생성되지 않은 경우 객체를 삭제합니다. 현재 블록 외부의 링크가 수신된 경우 이러한 링크가 살아있는 동안 개체를 삭제하지 마십시오. 그러면 확장성이 나타나고 인코더는 삭제를 지속적으로 모니터링할 필요가 없습니다. , 그리고 프로그램을 종료하면 로그에 메모리 누수 오류가 있음을 보장합니다... 그리고 자랑스러운 코드 최적화 프로그램은 이때 어디를 보고 있나요?)

이것은 또한 많은 놀라움입니다. 결국 그는 모든 누출된 바이트를 확실히 알고 있으며 이를 해제하고 싶지 않습니다. 그래서 현재 그는 다이노 포인터를 전혀 따르지 않습니까? 요청된 메모리와 마지막에 해제된 메모리 간의 차이만 계산합니다.

그리고 수명과 비어 있음/잃어버린 포인터는 문제 중 하나일 뿐입니다. 훨씬 이전에 객체에 대한 포인터의 암시적 캐스팅과 관련된 문제에 대해 논의했습니다. 이는 완전한 쓰레기입니다. 실수로(따라서 컴파일러는 그러한 코드가 컴파일되는 것을 허용하지 않아야 함) 예상 포인터 대신 다음을 얻을 수 있습니다. 예를 들어, 차례로 아무데도 가리킬 수 없음). 글쎄, 당신은 비교 연산에 대해 썼습니다. 또한 매우 모호합니다.

 
SemenTalonov :

1. 이것도 많이 놀랐다. 결국 그는 누출된 모든 바이트를 확실히 알고 있으며 이를 해제하고 싶지 않습니다. 그래서 현재 그는 다이노 포인터를 전혀 따르지 않습니까? 요청된 메모리와 마지막에 해제된 메모리 간의 차이만 계산합니다.

2. 수명 및 비어 있거나/잃어버린 포인터는 문제 중 하나일 뿐입니다.

1. 실제로는 그렇지 않습니다. 개발자를 위한 동적 개체에 대한 간단한 GC를 작성하는 것은 케이크 조각일 것입니다. 그러나 그들은 코더가 프로그램에 결함이 있음을 알 수 있도록 의도적으로 이러한 메시지를 남겼습니다. 그들의 동적 객체는 그런 세미 C#이기 때문에(나는 그것에 대한 전문가는 아니지만 내가 들은 바에 따르면) - 마치 객체가 같은 방식으로 행동하는 것처럼(포인터는 없지만 모든 것이 객체임), 생각한 하위 시스템은 개발되지 않았습니다.

2. 예, 물론 개체 변수가 동일한 유형인 경우(즉: 자동으로 또는 독립적으로 삭제되는 것이 아니라 참조가 없는 경우 내장된 가비지 수집기에 의해 삭제됨) 해당 변수에 대한 모든 액세스는 엄격하게 균일하게 발생합니다.