앗. 지원 질문 - 페이지 11

 
Interesting :

읽을 수 있어서 좋네요... :)

내가 이해하는 바와 같이 이 두 가지 접근 방식 모두 하나의 매개변수(유형은 다르지만)만 전송/읽도록 설계되었지만 나쁜 접근 방식은 아닙니다.

그러나 많은 매개변수가 있고 모든 매개변수를 기본 클래스에 집어넣을 수 없다면 얼마나 흥미로운 일입니까?

내가 이해하는 한, 우리가 전달하는 매개변수의 인덱스를 추가로 입력하십시오(클래스에서도 인덱스별로 쌓인 매개변수가 있는 배열을 만들 수 있음)?

같은거 이해못했는데...

내 예에는 인덱스가 있지만 명시 적으로 숫자가 아니라 열거입니다....

 

잊어 버려, 가치가 없습니다.

 

Interesting :

예델킨 :

일반적으로 https://www.mql5.com/ru/forum/3566/page6#comment_58280 문제에 대한 토론 후 이사회에 요청을 보냈습니다.

1. 몰라, 몰라.

개발자는 보안을 위해 기능을 희생하면서 특정 조치를 취하지 않을 것 같습니다(한편으로는 맞습니다).

나는 보고한다.

요청은 이랬습니다.
...

나는 제안한다:

1. Shapes[10] 배열을 CShape에서 파생된 클래스의 인스턴스로 올바르게 채우는 방법을 나타내기 위해 핸드북의 "다형성" 섹션을 명확히 하십시오(예시 제공).

2. 줄의 철자를 확인합니다.

CShape[ 10 ] shapes;                       // массив объектов CShape

3. 클래스를 선언할 때 선언된 클래스 이름 바로 뒤에 중괄호를 넣어야 하는지 설명합니다.

클래스 CShape{};

클래스 CCircle{}: 공개 CShape

클래스 CSquare{}: 공개 CShape

답변:

라시드 우마로프 2011.04.11 15:17

도움말을 작성할 당시에는 문서화에 대해 아직 명확하지 않은 부분이 있었습니다. 이 순간을 수정하고 올바른 코드를 추가하겠습니다. 메시지를 보내주셔서 감사합니다.

자세한 설명이 도움말에 추가됩니다. 여기에서 발췌했습니다.

프로그램에서 다른 유형(CCircle 및 CSquare)의 개체를 사용하지만 동일한 기본 유형 CShape에서 상속된다고 가정합니다. 다형성을 사용하면 기본 유형 CShape의 개체 배열을 만들 수 있지만 이 배열을 선언할 때 개체 자체는 여전히 알 수 없고 해당 유형은 정의되지 않습니다.

배열의 각 요소에 포함될 객체 유형에 대한 결정은 프로그램 실행 중에 직접 이루어집니다. 이것은 각 클래스의 객체를 동적으로 생성한다는 것을 의미하므로 객체 자체 대신 객체 포인터를 사용해야 합니다.

객체를 동적으로 생성하려면 new 연산자가 사용되며 이러한 각 객체는 delete 연산자를 사용하여 독립적이고 명시적으로 삭제되어야 합니다. 따라서 CShape 유형의 포인터 배열을 선언하고 각 요소에 대해 스크립트 예제와 같이 필요한 유형( new Class_name) 의 객체를 생성합니다.

 //+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart ()

  {

//--- объявим массив указателей объектов базового типа 

   CShape *shapes[ 5 ];   // массив указателей на объекты CShape



//--- здесь заполняем массив производными объектами

//--- объявим указатель на объект типа CCircle

   CCircle *circle= new CCircle();

//--- задаем свойства объекта по указателю circle

   circle.SetRadius( 2.5 );

//--- поместим в shapes[0] значение указателя

   shapes[ 0 ]=circle;



//--- создаем еще один объект CCircle и запишем его указатель в shapes[1]

   circle= new CCircle();

   shapes[ 1 ]=circle;

   circle.SetRadius( 5 );



//--- тут мы намеренно "забыли" задать значение для shapes[2]

//circle=new CCircle();

//circle.SetRadius(10);

//shapes[2]=circle;



//--- для неиспользуемого элемента установим значение NULL

   shapes[ 2 ]= NULL ;



//--- создаем объект CSquare и запишем его указатель в shapes[3]

   CSquare *square= new CSquare();

   square.SetSide( 5 );

   shapes[ 3 ]=square;



//--- создаем объект CSquare и запишем его указатель в shapes[4]

   square= new CSquare();

   square.SetSide( 10 );

   shapes[ 4 ]=square;



//--- массив указателей есть, получим его размер

   int total= ArraySize (shapes);

//--- пройдем в цикле по всем указателям в массиве 

   for ( int i= 0 ; i< 5 ;i++)

     {

       //--- если по указанному индексу указатель является валидным

       if ( CheckPointer (shapes[i])!= POINTER_INVALID )

        {

         //--- выведем в лог тип и площадь фигуры

         PrintFormat ( "Объект типа %d имеет площадь %G" ,

               shapes[i].GetType(),

               shapes[i].GetArea());

        }

       //--- если указатель имеет тип POINTER_INVALID

       else

        {

         //--- сообщим об ошибке

         PrintFormat ( "Объект shapes[%d] не инициализирован! Его указатель %s" ,

                     i, EnumToString ( CheckPointer (shapes[i])));

        }

     }



//--- мы должны самостоятельно уничтожить все созданные динамические объекты

   for ( int i= 0 ;i<total;i++)

     {

       //--- удалять можно только объекты, чей указатель имеет тип POINTER_DYNAMIC

       if ( CheckPointer (shapes[i])== POINTER_DYNAMIC )

        {

         //--- сообщим об удалении

         PrintFormat ( "Удаляем shapes[%d]" ,i);

         //--- уничтожим объект по его указателю

         delete shapes[i];

        }

     }

  }


객체가 삭제 연산자에 의해 파괴되면 포인터의 유형을 확인해야 합니다. POINTER_DYNAMIC 포인터가 있는 개체만 삭제를 사용하여 삭제할 수 있습니다. 다른 유형의 포인터에 대해서는 오류가 수신됩니다.

이 예제는 포인터 배열을 만드는 아이디어를 완전히 드러낸다고 생각합니다.
라시드 우마로프 2011.04.11 10:31

메시지를 보내주셔서 감사합니다. #2와 #3을 수정했습니다. 새 버전의 도움말에 포함될 예정입니다.



 

문제. 표준 라이브러리 는 다음 행을 사용합니다.

 void CTrade::Request( MqlTradeRequest & request) const
  {...}

참조는 " const 지정자는 구조 및 클래스의 구성원에 적용되지 않습니다."라고 말합니다. 위의 클래스 메서드에서 const 를 사용하는 것은 무엇을 의미하며 이와 같은 경우에 사용하기 위한 규칙은 무엇입니까?

Документация по MQL5: Стандартная библиотека
Документация по MQL5: Стандартная библиотека
  • www.mql5.com
Стандартная библиотека - Документация по MQL5
 

Yedelkin :

..............

위의 클래스 메서드 에서 const 를 사용하는 것은 무엇을 의미하며 이와 같은 경우에 사용하기 위한 규칙은 무엇입니까?

아, 저도 궁금했습니다. 나는 "게임의 규칙"을 충분히 알고 의미있게 언어를 사용하고 싶습니다.
 
Yedelkin :

문제. 표준 라이브러리 는 다음 행을 사용합니다.

참조는 " const 지정자는 구조 및 클래스의 구성원에 적용되지 않습니다."라고 말합니다. 위의 클래스 메서드에서 const 를 사용하는 것은 무엇을 의미하며 이와 같은 경우에 사용하기 위한 규칙은 무엇입니까?

구조체/클래스의 멤버는 한 가지지만 메서드는 다른 것입니다.

const로 선언된 메서드는 해당 클래스의 상태/멤버를 변경하지 않음을 의미합니다. 즉, 이러한 메서드를 호출한 후에도 클래스의 내부 상태는 변경되지 않은 상태로 유지됩니다. 클래스 멤버를 변경하려는 시도를 확인하도록 컴파일러에 추가로 지시하는 데 사용됩니다.

 
Renat :

구조체/클래스의 멤버 는 한 가지지만 메서드는 다른 것입니다.

const로 선언된 메서드는 해당 클래스의 상태/멤버를 변경하지 않음을 의미합니다. 즉, 이러한 메서드를 호출한 후에도 클래스의 내부 상태는 변경되지 않은 상태로 유지됩니다. 클래스 멤버를 변경하려는 시도를 확인하도록 컴파일러에 추가로 지시하는 데 사용됩니다.

우와. 고맙습니다! 그리고 나는 내 머리를 부러뜨렸다.

 
TheXpert :
그건 그렇고, 대화가 나온 이후로 논리적 인 질문이 있습니다. 휘발성 지시가없고 예상되지 않습니까?

그리고 어떻게 적용할 수 있습니까? , 흐름이 서로 상호 작용하지 않기 때문에

이제 스레드 간에 데이터를 자유롭게 전송할 수 있다면 예, 그러한 명령이 필요합니다.

 
코드, 나는 내가 뭔가를 잘못 쓰고 있다고 생각하고 썼습니다 :) 이제 무엇을 이해했는지 이해합니다. 물론 휘발성 이 아닙니다. 변경 가능합니다 :))
 
class COracleTemplate
  {
private :
public :
   string             filename;
                     COracleTemplate(){Init();};
                    ~COracleTemplate(){DeInit();};
   virtual void       Init(){filename= this .Name(); Print ( "loadSettings from " ,filename);};
   virtual void       DeInit(){ Print ( "saveSettings to " ,filename);};
   virtual string     Name(){ return ( "Prpototype" );};
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CCO2: public COracleTemplate
  {
   virtual string     Name(){ return ( "CO2" );};
  };
class CH2O: public COracleTemplate
  {
   virtual string     Name(){ return ( "H2O" );};
  };
COracleTemplate* CO2,*H2O;
void OnStart ()
  {
   CO2= new CCO2;
   Print (CO2.Name(), " filename=" ,CO2.filename);
   delete CO2;
   
   H2O= new CH2O;
   Print (H2O.Name(), " filename=" ,H2O.filename);
   delete H2O;
   
  }

안녕하세요.

질문

위의 코드로

내가 무엇을 잘못했거나 기본적으로 MT5에서 달성할 수 없습니까?

나는 (내가 당연하다고 생각하는 것처럼) - 파일 이름 변수에서 재정의된 이름을 받고 싶습니다 ...