앗. 지원 질문 - 페이지 8

 
Interesting :

1. 자손의 기능을 사용할 수 없습니다. 누가, 어떻게 했는지는 모르겠으나 개인적으로 Array에서 SetRadius(), SetSide()에 접근하지 못해서 autogen으로 문제를 해결할 수 있는 방법이 있을지도 모르지만, 없으면 좋겠다.

2. 이 방법으로 포인터로 작업하지 않을 수도 있지만 항상 누수가 발생하거나 주요 작업이 진행 중인 블록에서 포인터를 바로 맞아야 합니다.

모든 것을 사용할 수 있습니다 ... 위의 내 게시물
 
equivalent23 :

예를 들어도 될까요?

내가 준 예제는 문서에서 가져온 것이며 어떻게 작동해야하는지 명확하지 않습니다.

그것이 작동하는 방식입니다. 그러나 문서에 따르면 전혀 아닙니다 :/ (하지만 다시 한 번 포인터에 대해 연습했습니다)

 #property copyright "Ya"
#property link       "Ya"
#property version   "1.00"
//--- Базовый класс
class CShape
  {
protected :
   int                m_type;                 // тип фигуры
   int                m_xpos;                 // X - координата точки привязки
   int                m_ypos;                 // Y - координата точки привязки
public :
   void            CShape(){m_type= 0 ;};   // конструктор, тип равен нулю
   int             GetType(){ return (m_type);}; // возвращает тип фигуры
   virtual void            SetRadius( double r){ return ;};
   virtual void            SetSide( double s){ return ;};
   virtual double          GetArea(){ return ( 0 ); } // возвращает площадь фигуры
  };
//--- производный класс Круг
class CCircle: public CShape           // после двоеточия указывается базовый класс,
  {                                       // от которого производится наследование 
private :
   double             m_radius;               // радиус круга

public :
   void            CCircle(){m_type= 1 ; m_radius= 10 ;};   // конструктор, тип равен 1 
   virtual void            SetRadius( double r){m_radius=r;};
   virtual double GetArea(){ return ( 3.14 *m_radius*m_radius);} // площадь круга
  };
//--- производный класс Квадрат
class CSquare: public CShape           // после двоеточия указывается базовый класс,
  {                                       // от которого производится наследование 
private :
   double             m_square_side;         // сторона квадрата

public :
   void             CSquare(){m_type= 2 ;}; // конструктор, тип равен 2 
   virtual void             SetSide( double s){m_square_side=s;};
   virtual double GetArea(){ return (m_square_side*m_square_side);} //площадь квадрата
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart ()
  {
   CCircle *ci= new CCircle;
   CSquare *sq= new CSquare;
   CShape  *shapes[ 2 ];                       // массив объектов CShape

   shapes[ 0 ]=ci;
   shapes[ 1 ]=sq;
////---зададим уникальные свойства объектов
   shapes[ 0 ].SetRadius( 5.0 );
   shapes[ 1 ].SetSide( 4.0 );
   for ( int i= 0 ; i< 2 ;i++)
     {
       //--- тип и площадь фигуры
       Print ( "Объект типа " +shapes[i].GetType()+ " имеет площадь " +shapes[i].GetArea());
     }
 
AlexSTAL :

하다:

가상화를 통해 훨씬 쉽게 만들 수 있습니다.


나는 그것에 대해 말하는 것이 아니다. 단순히 포인터를 사용 하는 것이 아니라 기본 클래스 유형이 있는 해당 포인터의 배열을 사용하는 것입니다.

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

단순 배열이든 포인터 배열이든 상관없으며 기본 클래스에 작성된 내용만 사용할 수 있습니다.

글쎄, 또는 나는 뭔가를 이해하지 못합니다.

예를 들어, 약간 수정된 기본 클래스(구조체로 스타일 지정)

 //class CShape
struct CShape
//Базовый класс
{  
protected : 
int             m_type;                 // тип фигуры
int             m_xpos;                 // X - координата точки привязки
int             m_ypos;                 // Y - координата точки привязки

public :
void            CShape(){m_type= 0 ;};   // конструктор, тип равен нулю
int             GetType(){ return (m_type);}; // возвращает тип фигуры

void            SetPosX( int s){m_xpos=s;};
int             GetPosX(){ return (m_xpos);};

void            SetPosY( int s){m_ypos=s;};
int             GetPosY(){ return (m_ypos);};

double GetArea(){ return ( 0 ); } // возвращает площадь фигуры

};

이 모든 것을 이와 같은 배열에 넣으면 최소한 기본 클래스에서 선언된 기능에 액세스할 수 있습니다.

문제는 배열이 기본 클래스 유형인 경우(즉, 배열이 CShape 유형인 경우) 하위 기능에 액세스하는 방법입니다.

Когда нужно использовать указатели в MQL5
Когда нужно использовать указатели в MQL5
  • 2010.03.25
  • MetaQuotes Software Corp.
  • www.mql5.com
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
 
Interesting :

나는 그것에 대해 말하는 것이 아니다. 단순히 포인터를 사용 하는 것이 아니라 기본 클래스 유형이 있는 해당 포인터의 배열을 사용하는 것입니다.

문제는 배열이 기본 클래스 유형인 경우(즉, 배열이 CShape 유형인 경우) 하위 기능에 액세스하는 방법입니다.

나는 마지막 페이지에 다음과 같이 썼습니다.

 class CBase
  {
public :
   void m_radius() { Print ( "CBase" );}
  };

class CTest : public CBase
  {
public :
   void m_radius() { Print ( "CTest" );}
  };

CBase* Base;

void OnStart ()
  {
   Base = new CTest;
   Base.m_radius();
   ((CTest *)Base).m_radius();
   delete Base;
  }
 

배열만 있는 동일한 코드:

 class CBase
  {
public :
   void m_radius() { Print ( "CBase" );}
  };

class CTest : public CBase
  {
public :
   void m_radius() { Print ( "CTest" );}
  };

CBase* Base[ 1 ];

void OnStart ()
  {
   Base[ 0 ] = new CTest;
   Base[ 0 ].m_radius();
   ((CTest *)Base[ 0 ]).m_radius();
   delete Base[ 0 ];
  }
 
Yedelkin :

그것이 작동하는 방식입니다. 그러나 문서에 따르면 전혀 아닙니다 :/

글쎄, 나는 실제로 같은 것에 대해 이야기하고 있습니다. 최소한 기본 클래스의 모든 기능을 지정하는 것이 필요합니다(그렇지 않으면 액세스할 수 없음).
 
AlexSTAL :

하다:

이에 대한 내용은 다음과 같습니다.

((CTest *)Base).m_radius();

키보드 압수와 함께 손을 찢을 필요가 있습니다.

C ++에서는 dynamic_cast를 사용하여 클래스 계층을 따라 이동할 수 있지만 그건 그렇고, 거기에서도 좋아하지 않습니다. MQL에서 이는 암시적 충돌을 일으킬 수 있습니다. 버그는 다른 곳에 있습니다.

따라서 그러한 캐스트를 사용하는 것은 절대 권장하지 않습니다. 즉, 일반적으로. 조상들에게도, 아이들에게도.

 
TheXpert :

이에 대한 내용은 다음과 같습니다.

키보드 압수와 함께 손을 찢을 필요가 있습니다.

C ++에서는 dynamic_cast를 사용하여 클래스 계층을 따라 이동할 수 있지만 그건 그렇고, 거기에서도 좋아하지 않습니다. MQL에서 이것은 암시적 충돌을 일으킬 수 있습니다. 버그는 다른 곳에 있습니다.

따라서 그러한 캐스트를 사용하는 것은 절대 권장하지 않습니다. 즉, 일반적으로. 조상들에게도, 아이들에게도.

부드럽게 대답하는 법 ....

프로그래머의 머리가 좋지 않으면 간단한 1 + 1 작업으로 인해 암시적 충돌이 발생할 수 있습니다....

그리고 MQL5는 C++가 아니라는 점에 주목하고 싶습니다.

적용의 문제가 아니라 가능성일 뿐입니다....

 
AlexSTAL :

배열만 있는 동일한 코드:


1. 조상에서 m_radius()를 제거합니다. 예제에는 없습니다. :) 그리고 OnStart()에서 작업을 하지 마십시오.

2. 삭제 Base[0] 행을 다른 곳으로 이동할 수 있습니까? 이것이 스크립트가 아니라 올빼미이고 배열의 데이터가 여전히 나에게 유용하다고 가정해 보겠습니다.

나는 즉시 메모리 누수가 발생합니다. 이러한 이유로 나는 구조로 전환해야했습니다 ...

 
Interesting :

1. m_radius()를 제거합니다. 예제에는 없습니다. 그리고 OnStart()에서 작업을 수행하지 마십시오.

2. 삭제 Base[0] 행을 다른 곳으로 이동할 수 있습니까? 이것이 스크립트가 아니라 올빼미이고 배열의 데이터가 여전히 나에게 유용하다고 가정해 보겠습니다.

나는 즉시 메모리 누수가 발생합니다. 이러한 이유로 나는 구조로 전환해야했습니다 ...

1) 제거, 작동:

 class CBase
  {
public :
  };

class CTest : public CBase
  {
public :
   void m_radius() { Print ( "CTest" );}
  };

CBase* Base[ 1 ];

void OnStart ()
  {
   Base[ 0 ] = new CTest;
   ((CTest *)Base[ 0 ]).m_radius();
   delete Base[ 0 ];
  }
2) 가장 중요한 것은 프로그램이 끝나기 전에 삭제하는 것입니다... 하지만 이 포인터를 함수에 생성했다면 전역 위치에 저장해야 합니다...