MQL4에서 싱글톤 패턴을 구현할 수 있습니까? - 페이지 9

 
hoz :

나는 이것을 좋아했다:

그러나 어떤 이유로 컴파일하는 동안 많은 오류가 있습니다. 뭐가 문제 야?

다소 간단한 Myers Singleton을 MQL4++로 전송하려는 시도는 예를 들어 다음과 같습니다.

 #property strict

/******************************************************************************/
class Symbol_Properties {
private :
   // Реализация технической части singleton'а
   /******************************************************************************/
public : // Вечно в этом MQL4++ что-то не работает: 'Symbol_Properties::Symbol_Prope…' - cannot call private member function
  Symbol_Properties() {};
private : // Восстанавливаем private
  Symbol_Properties( const Symbol_Properties &p);
   void operator =( const Symbol_Properties &);

public :
   static Symbol_Properties *singleton() {
     static Symbol_Properties sp;
     return GetPointer (sp);
  }

   // Пользовательская часть singleton'а
   /******************************************************************************/
   datetime     gdt_Quote;           // Время поступления последней котировки
   double       gda_Price [ 2 ];       // Текущие рыночные цены (0 - Bid, 1- Ask)
   double       gd_Spread;           // Размер спреда в пунктах
   double       gd_Swap;             // Своп
   double       gd_Comission;         // Комиссия
   double       gd_Pt;               // Величина одного пункта
   int          gi_Digits;           // Количество знаков в цене после запятой
   int          gi_StopLevel;         // Минимально-допустимый уровень стоп-лосса/тейк-профита в пунктах
   int          gi_FreezLevel;       // Уровень заморозки ордеров в пунктах
};

/******************************************************************************/
void change() {
  Symbol_Properties *p = Symbol_Properties::singleton(); // Получение singleton'а

  p.gdt_Quote = TimeCurrent ();
  p.gda_Price[ 0 ] = Bid;
  p.gda_Price[ 1 ] = Ask;
}

/******************************************************************************/
void OnStart () {
  Symbol_Properties *p = Symbol_Properties::singleton(); // Получение singleton'а

   Print ( "gdt_Quote = " , p.gdt_Quote, ", Price = " , p.gda_Price[ 0 ], "/" , p.gda_Price[ 1 ]);
  change();
   Print ( "gdt_Quote = " , p.gdt_Quote, ", Price = " , p.gda_Price[ 0 ], "/" , p.gda_Price[ 1 ]);
}

실행 결과:

 01 : 24 : 57 Script 3 EURUSDm,H1: loaded successfully
01 : 24 : 57 3 EURUSDm,H1: initialized
01 : 24 : 57 3 EURUSDm,H1: gdt_Quote = 1970.01 . 01 00 : 00 : 00 , Price = 0.0 / 0.0
01 : 24 : 57 3 EURUSDm,H1: gdt_Quote = 2014.09 . 03 21 : 24 : 57 , Price = 1.31461 / 1.3148
01 : 24 : 57 3 EURUSDm,H1: uninit reason 0
01 : 24 : 57 Script 3 EURUSDm,H1: removed

정적 singleton() 메서드에서 Symbol_Properties 유형의 정적 변수 가 생성되지만 메서드는 정적이지만 private을 포함한 모든 멤버에 액세스할 수 있으므로 컴파일하는 동안 잘못된 기본 생성자 호출 액세스 오류가 발생합니다. 따라서 MQL4++ 구현의 오류로 인해 이 생성자를 공개해야 했습니다. 그들이 그것을 고치면 더 이상 할 필요가 없습니다.

실행 결과는 change() 호출 후 데이터가 변경되었음을 보여줍니다. 이것은 내부의 change() 함수가 OnStart()에서 받은 것과 동일한 객체의 주소를 받았다는 것을 간접적으로 나타냅니다.

이제 MQL4++의 버그로 인해 기본 생성자가 공용이기 때문에 이러한 개체가 많이 생성될 수 있으므로 이것은 전혀 싱글톤이 아닙니다. 오류가 수정되고 기본 생성자가 private 섹션에 배치되면 MQL4++에서 Myers' Singleton의 본격적인 구현이 됩니다.

 
ALXIMIKS :

stuct와 클래스에서 static이 다르게 행동하는 고통의 2일 동안을 이해하지 못하셨나요???

그 과정에서 구조는 C에서 가져오고 상속 측면에서 약간만 펌핑되었습니다.

스윙 클래스, 그들은 가득 찼습니다.

이 때문에 정적 변수를 위한 구조의 공간을 예약할 필요가 없습니다.

수업에서 그렇지 않으면 장소를 예약해야합니다.

사실이 아닙니다. 이 멋진 MQL4++ 컴파일러는 다르게 작동합니다. 동작이 "정렬"되기 때문에 객체의 인스턴스를 생성하기만 하면 됩니다.

 #property strict

/******************************************************************************/
struct A {
   static int x;
};

/******************************************************************************/
void OnStart () {
  A y;
}

어떤 이유로 컴파일되지 않습니다(첫 번째와 세 번째는 경고이고, 여기서 두 번째는 본격적인 오류입니다).

 struct has no members, size assigned to 1 byte
unresolved static variable 'A::x'
variable 'y' not used

그렇다면 구조에서 "정적 변수를 위한 장소"를 예약해야 합니까?

그리고 터미널/컴파일러의 다음 버전에서는 동일할까요? (버전을 변경할 때 이전에 작성된 모든 것을 수정하기 위해 서두르지 않도록)

 
TheXpert :

캡슐화를 잊어 버렸습니다. 그리고 삭제할 수 있습니다. 하지만 여기에는 상수 포인터가 없습니다.) 그리고 일반적으로 싱글톤이 최상의 패턴은 아닙니다.

템플릿이 있으면 좋습니다. 수업의 경우 아마도 꿈일 것입니다.



글쎄, 그는 최악 또는 최고, 내가 판단하지 않을 것입니다.

위에서 반복적으로 언급한 메모리 관리 모드(자동, 동적, 정적, 기반)는 OOP가 아무리 강력하더라도 템플릿에 적용할 수 없음을 토론 참가자에게 상기시켜 드리겠습니다.

 
Так обязательно ли резервировать в структурах "место под static-переменную"?
"예", 그것은 당신이 할 수 있고 "아니오"로 할 수 있다는 것을 알아차렸지만, 그렇게 해서는 안 됩니다.
 
simpleton :


이제 MQL4++의 버그로 인해 기본 생성자가 공용이기 때문에 이러한 개체가 많이 생성될 수 있으므로 이것은 전혀 싱글톤이 아닙니다. 오류가 수정되고 기본 생성자가 private 섹션에 배치되면 MQL4++에서 Myers' Singleton의 본격적인 구현이 됩니다.


감사합니다. 여기 포인터를 가져갈 수 있는지 몰랐습니다.

코드로 무언가를 만들었습니다. 더 간단할 수 있습니다. 템플릿이 없는 것은 유감입니다.

코드를 붙여넣을 수 없습니다

클래스 싱글턴{

사적인:

클래스 SomeClass{

공공의:

정수

};

하나씩 일어나는 것(){}

~싱글톤(){}

공공의:

정적 SomeClass* 인스턴스(){

정적 SomeClass a();

반환 GetPointer(a);

}

};

무효 OnStart()

{

SomeClass* some_ptr = 싱글톤::인스턴스();

some_ptr.a = 5;

경고(some_ptr.a);

}

 
ALXIMIKS :


감사합니다. 여기 포인터를 가져갈 수 있는지 몰랐습니다.

코드로 무언가를 만들었습니다. 더 간단할 수 있습니다. 템플릿이 없는 것은 유감입니다.

코드를 붙여넣을 수 없습니다

클래스 싱글턴{

사적인:

클래스 SomeClass{

공공의:

정수

};

하나씩 일어나는 것(){}

~싱글톤(){}

공공의:

정적 SomeClass* 인스턴스(){

정적 SomeClass a();

반환 GetPointer(a);

}

};

무효 OnStart()

{

SomeClass* some_ptr = 싱글톤::인스턴스();

some_ptr.a = 5;

경고(some_ptr.a);

}

다음은 C++용 Myers 코드입니다.

 class Singleton
{
private :
    Singleton() {}
    Singleton( const Singleton&);
    Singleton& operator =( Singleton& );
public :
     static Singleton& getInstance() {
         static Singleton  instance;
         return instance;
    }
};

다음은 MQL4++로 번역되고 예제에서 클래스의 기술적인 부분인 동일한 코드입니다.

 class Symbol_Properties {
private :
   // Реализация технической части singleton'а
   /******************************************************************************/
public : // Вечно в этом MQL4++ что-то не работает: 'Symbol_Properties::Symbol_Prope…' - cannot call private member function
  Symbol_Properties() {};
private : // Восстанавливаем private
  Symbol_Properties( const Symbol_Properties &p);
   void operator =( const Symbol_Properties &);

public :
   static Symbol_Properties *singleton() {
     static Symbol_Properties sp;
     return GetPointer (sp);
  }

여기 "지혜"가 어디에 있습니까?

귀하의 예는 MQL4++ 컴파일러의 오류를 악용합니다. 특히 OnStart()에서 SomeClass 유형을 사용하는 것은 싱글톤 클래스의 중첩 유형이고 "성인용" 컴파일러가 즉시 오류를 감지하기 때문에 불법입니다.

try.cpp:33:9: error: unknown type name 'SomeClass'
        SomeClass* some_ptr = Singleton::Instance();
        ^

그러나 중첩 유형을 올바르게 지정할 수 있으므로 이것은 매우 기본적인 사항은 아닙니다. 훨씬 더 근본적으로 SomeClass 유형은 Singleton 클래스의 private 섹션에서 선언되므로 OnStart()에서 SomeClass를 사용하는 것은 이제 근본적으로 불법이며 "성인" 컴파일러는 즉시 보고합니다.

 try .cpp: 33 : 20 : error: 'SomeClass' is a private member of 'Singleton'
        Singleton::SomeClass* some_ptr = Singleton::Instance();
                   ^

MQL4++ 컴파일러가 액세스 제어로 난교를 수정하지 않으면 구현이 작동합니다.

 

1. Maers가 아니라 Maers, 차이점은 ... 웁스, 가장 중요한 것은 코드가 작동하고 필요한 작업을 수행하며 오류 없이 ++가 아니라 MQL 에서 수행된다는 것입니다.

2. 코드가 제대로 작동합니까? 아니, 기간. 왜 그렇게 많은 징징이 있는지 서비스 데스크에 쓰십시오. 모두가 원하고 할 수 있는 모든 것을 이미 이해했습니다.

3. 내 예는 MQL에서 오류(C++에 비해)를 우회하는 방법을 보여주었습니다. 마음에 들지 않으면 1번과 2번 항목을 참조하십시오.

4. private 클래스에 대한 포인터 생성에 대해 - 네, 이것은 MQL 보블이지만 자동으로 타입을 결정하는 기능이 없기 때문에 그렇게 작동하는 것이 좋습니다. \

(p.s. 제가 자동계정을 너무 과하게 썼는지 확인이 필요합니다)

5. MQL에서 포인터를 역참조하여 개체를 가져오는 방법을 찾지 못했기 때문에 개인 복사 생성자와 할당 연산자 가 중복되는 것으로 간주합니다.

그것들을 사용해보십시오, 나는 방법을 알게되어 기쁠 것입니다))

 
ALXIMIKS :

1. Maers가 아니라 Maers, 무엇이... 이런 차이점이 있습니다. 가장 중요한 것은 ++가 아니라 MQL에서 오류 없이 코드가 작동하고 필요한 작업을 수행 한다는 것입니다.

2. 코드가 제대로 작동합니까? 아니, 포인트. 왜 그렇게 많은 징징이 있는지 서비스 데스크에 쓰십시오. 모두가 원하고 할 수 있는 모든 것을 이미 이해했습니다.

3. 내 예는 MQL에서 오류(C++에 비해)를 우회하는 방법을 보여주었습니다. 마음에 들지 않으면 1번과 2번 항목을 참조하십시오.

4. private 클래스에 대한 포인터 생성에 대해 - 네, 이것은 MQL 보블이지만 자동으로 타입을 결정하는 기능이 없기 때문에 그렇게 작동하는 것이 좋습니다. \

(p.s. 제가 자동계정을 너무 과하게 썼는지 확인이 필요합니다)

5. MQL에서 포인터를 역참조하여 개체를 가져오는 방법을 찾지 못했기 때문에 개인 복사 생성자와 할당 연산자가 중복되는 것으로 간주합니다.

그것들을 사용해보십시오, 나는 방법을 알게되어 기쁠 것입니다))

1. 지금 - 필요하지만 필요한 것은 아닙니다(아래 설명 참조).

2. 수정하지 않으면 수정하지 않습니다. 그리고 그것은 전혀 구현되지 않을 것입니다.

3. 이것은 오류를 우회하는 방법이 아니라 악용하는 방법입니다.

4. 여기에 없는 것이 많습니다.

5. 이 버전에서는 그런 일이 가능할 수도 있는데, 특히 복사 생성자가 합성되지 않았다는 것이 내 눈앞에서 번쩍이는 것 같지만 이것이 향후 버전에서 합성이 시작되지 않는다는 보장은 아닙니다. 그들의 선언에 대한 간접 비용은 무시할 수 있다고 생각합니다.

이제 귀하의 코드에 이전 메시지에서 언급한 잠재적인 문제가 있을 뿐만 아니라 원칙적으로 싱글톤이 아니며 또한 액세스로 난교를 수정하는지 여부에 관계없이 왜 귀하의 코드에 문제가 있는지 설명합니다.

 #property strict

class Singleton{
private :
         class SomeClass{
         public :
             int a;
         };
        Singleton(){}
        ~Singleton(){}   
public :
         static SomeClass* Instance(){
                         static SomeClass a;
                         return GetPointer (a);
                }
        };
         int i;

void OnStart ()
{       
        SomeClass* some_ptr = Singleton::Instance();
        SomeClass obj1;
        SomeClass obj2;

        obj1.a = 3 ;
        obj2.a = 7 ;

        some_ptr.a = 5 ;
         Print ( "some_ptr.a = " , some_ptr.a);          
         Print ( "obj1.a = " , obj1.a);          
         Print ( "obj2.a = " , obj2.a);          
}

이 코드는 매우 성공적으로 실행되고 있습니다.

 10 : 09 : 27 Script 3 EURUSDm,H1: loaded successfully
10 : 09 : 27 3 EURUSDm,H1: initialized
10 : 09 : 27 3 EURUSDm,H1: some_ptr.a = 5
10 : 09 : 27 3 EURUSDm,H1: obj1.a = 3
10 : 09 : 27 3 EURUSDm,H1: obj2.a = 7
10 : 09 : 27 3 EURUSDm,H1: uninit reason 0
10 : 09 : 27 Script 3 EURUSDm,H1: removed

얼마나 많은 싱글톤을 만들었는지 확인하고 동시에 존재합니까?

액세스 권한이 있는 난교가 수정되면 이러한 의미에서 코드에 변화가 있습니까?

내 코드에서 변경됩니까?

당신이 생각을 더 범주적으로 말할수록 그것이 더 진실될 것이라고 생각합니까?

 

네, 관심을 가져주셔서 감사합니다. 맞습니다. 이 버전에서는 싱글톤도 아닙니다.

암시적 생성자 및 연산자에 대해 - 명시적으로 만들고 사용하려고 하면 개체에 대한 포인터의 이름을 변경하는 것이 불가능하기 때문에 작동하지 않는 것 같습니다.

작동하지 않는 이유, 'ptr' - 보호된 멤버 함수 를 호출할 수 없습니다. :

 class smart_ptr{
            Singleton* ptr;
       public :        
            smart_ptr(Singleton* val): ptr(val){}          
            smart_ptr(): ptr( NULL ){} 
            ~smart_ptr(){ delete ptr;}
      };
 
ALXIMIKS :

네, 관심을 가져주셔서 감사합니다. 맞습니다. 이 버전에서는 싱글톤도 아닙니다.

암시적 생성자 및 연산자에 대해 - 명시적으로 만들고 사용하려고 하면 개체에 대한 포인터의 이름을 변경하는 것이 불가능하기 때문에 작동하지 않는 것 같습니다.

작동하지 않는 이유, 'ptr' - 보호된 멤버 함수를 호출할 수 없습니다. :

별거 아닌거 같지만 아직까지 많은 떡밥이 있습니다. 소수만이 이것을 알아차리는 것이 유감입니다. 논란에 휩싸이고 싶지 않은데 사실 그 차이가 큽니다. C++의 구조에 적용되는 일부 사항은 MKL4에서 작동하지 않습니다. 그러나 나는 아무 말도하지 않을 것입니다 ... 그렇지 않으면 다음과 같은 질문을하기 시작할 것입니다.

"내가 왜 필요해?"

네, 적어도 그러면 미완성 교과서에 들어갈 수 없고, 그냥 MKL4에서 C++에서 작동하는 것을 작성하고 여기에서 작동하는지 여부에 대해 생각하지 마십시오. 이 단계에서 다른 것은 필요하지 않습니다 ...