개발자는 보안을 위해 기능을 희생하면서 특정 조치를 취하지 않을 것 같습니다(한편으로는 맞습니다).
나는 보고한다.
요청은 이랬습니다.
...
나는 제안한다:
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 |//+------------------------------------------------------------------+voidOnStart ()
{
//--- объявим массив указателей объектов базового типа
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_INVALIDelse
{
//--- сообщим об ошибкеPrintFormat ( "Объект shapes[%d] не инициализирован! Его указатель %s" ,
i, EnumToString ( CheckPointer (shapes[i])));
}
}
//--- мы должны самостоятельно уничтожить все созданные динамические объектыfor ( int i= 0 ;i<total;i++)
{
//--- удалять можно только объекты, чей указатель имеет тип POINTER_DYNAMICif ( CheckPointer (shapes[i])== POINTER_DYNAMIC )
{
//--- сообщим об удаленииPrintFormat ( "Удаляем shapes[%d]" ,i);
//--- уничтожим объект по его указателюdelete shapes[i];
}
}
}
객체가 삭제 연산자에 의해 파괴되면 포인터의 유형을 확인해야 합니다. POINTER_DYNAMIC 포인터가 있는 개체만 삭제를 사용하여 삭제할 수 있습니다. 다른 유형의 포인터에 대해서는 오류가 수신됩니다.
이 예제는 포인터 배열을 만드는 아이디어를 완전히 드러낸다고 생각합니다.
라시드 우마로프2011.04.11 10:31
메시지를 보내주셔서 감사합니다. #2와 #3을 수정했습니다. 새 버전의 도움말에 포함될 예정입니다.
읽을 수 있어서 좋네요... :)
내가 이해하는 바와 같이 이 두 가지 접근 방식 모두 하나의 매개변수(유형은 다르지만)만 전송/읽도록 설계되었지만 나쁜 접근 방식은 아닙니다.
그러나 많은 매개변수가 있고 모든 매개변수를 기본 클래스에 집어넣을 수 없다면 얼마나 흥미로운 일입니까?
내가 이해하는 한, 우리가 전달하는 매개변수의 인덱스를 추가로 입력하십시오(클래스에서도 인덱스별로 쌓인 매개변수가 있는 배열을 만들 수 있음)?
같은거 이해못했는데...
내 예에는 인덱스가 있지만 명시 적으로 숫자가 아니라 열거입니다....
잊어 버려, 가치가 없습니다.
Interesting :
일반적으로 https://www.mql5.com/ru/forum/3566/page6#comment_58280 문제에 대한 토론 후 이사회에 요청을 보냈습니다.
1. 몰라, 몰라.
개발자는 보안을 위해 기능을 희생하면서 특정 조치를 취하지 않을 것 같습니다(한편으로는 맞습니다).
나는 보고한다.
요청은 이랬습니다.나는 제안한다:
1. Shapes[10] 배열을 CShape에서 파생된 클래스의 인스턴스로 올바르게 채우는 방법을 나타내기 위해 핸드북의 "다형성" 섹션을 명확히 하십시오(예시 제공).
2. 줄의 철자를 확인합니다.
3. 클래스를 선언할 때 선언된 클래스 이름 바로 뒤에 중괄호를 넣어야 하는지 설명합니다.
클래스 CShape{};
클래스 CCircle{}: 공개 CShape
클래스 CSquare{}: 공개 CShape
답변:
자세한 설명이 도움말에 추가됩니다. 여기에서 발췌했습니다.
프로그램에서 다른 유형(CCircle 및 CSquare)의 개체를 사용하지만 동일한 기본 유형 CShape에서 상속된다고 가정합니다. 다형성을 사용하면 기본 유형 CShape의 개체 배열을 만들 수 있지만 이 배열을 선언할 때 개체 자체는 여전히 알 수 없고 해당 유형은 정의되지 않습니다.
배열의 각 요소에 포함될 객체 유형에 대한 결정은 프로그램 실행 중에 직접 이루어집니다. 이것은 각 클래스의 객체를 동적으로 생성한다는 것을 의미하므로 객체 자체 대신 객체 포인터를 사용해야 합니다.
객체를 동적으로 생성하려면 new 연산자가 사용되며 이러한 각 객체는 delete 연산자를 사용하여 독립적이고 명시적으로 삭제되어야 합니다. 따라서 CShape 유형의 포인터 배열을 선언하고 각 요소에 대해 스크립트 예제와 같이 필요한 유형( new Class_name) 의 객체를 생성합니다.
객체가 삭제 연산자에 의해 파괴되면 포인터의 유형을 확인해야 합니다. POINTER_DYNAMIC 포인터가 있는 개체만 삭제를 사용하여 삭제할 수 있습니다. 다른 유형의 포인터에 대해서는 오류가 수신됩니다.
메시지를 보내주셔서 감사합니다. #2와 #3을 수정했습니다. 새 버전의 도움말에 포함될 예정입니다.
문제. 표준 라이브러리 는 다음 행을 사용합니다.
참조는 " const 지정자는 구조 및 클래스의 구성원에 적용되지 않습니다."라고 말합니다. 위의 클래스 메서드에서 const 를 사용하는 것은 무엇을 의미하며 이와 같은 경우에 사용하기 위한 규칙은 무엇입니까?
Yedelkin :
..............
위의 클래스 메서드 에서 const 를 사용하는 것은 무엇을 의미하며 이와 같은 경우에 사용하기 위한 규칙은 무엇입니까?
문제. 표준 라이브러리 는 다음 행을 사용합니다.
참조는 " const 지정자는 구조 및 클래스의 구성원에 적용되지 않습니다."라고 말합니다. 위의 클래스 메서드에서 const 를 사용하는 것은 무엇을 의미하며 이와 같은 경우에 사용하기 위한 규칙은 무엇입니까?
구조체/클래스의 멤버는 한 가지지만 메서드는 다른 것입니다.
const로 선언된 메서드는 해당 클래스의 상태/멤버를 변경하지 않음을 의미합니다. 즉, 이러한 메서드를 호출한 후에도 클래스의 내부 상태는 변경되지 않은 상태로 유지됩니다. 클래스 멤버를 변경하려는 시도를 확인하도록 컴파일러에 추가로 지시하는 데 사용됩니다.
구조체/클래스의 멤버 는 한 가지지만 메서드는 다른 것입니다.
const로 선언된 메서드는 해당 클래스의 상태/멤버를 변경하지 않음을 의미합니다. 즉, 이러한 메서드를 호출한 후에도 클래스의 내부 상태는 변경되지 않은 상태로 유지됩니다. 클래스 멤버를 변경하려는 시도를 확인하도록 컴파일러에 추가로 지시하는 데 사용됩니다.
우와. 고맙습니다! 그리고 나는 내 머리를 부러뜨렸다.
그건 그렇고, 대화가 나온 이후로 논리적 인 질문이 있습니다. 휘발성 지시가없고 예상되지 않습니까?
그리고 어떻게 적용할 수 있습니까? , 흐름이 서로 상호 작용하지 않기 때문에
이제 스레드 간에 데이터를 자유롭게 전송할 수 있다면 예, 그러한 명령이 필요합니다.
안녕하세요.
질문
위의 코드로
내가 무엇을 잘못했거나 기본적으로 MT5에서 달성할 수 없습니까?
나는 (내가 당연하다고 생각하는 것처럼) - 파일 이름 변수에서 재정의된 이름을 받고 싶습니다 ...