OOP. Başvuru soruları - sayfa 8

 
Interesting :

1. Torunların işlevselliği mevcut değil. Kim ve nasıl bilmiyorum ama Dizi'den SetRadius() ve SetSide()'a şahsen erişemedim.Belki sorunu bir otojenle çözmenin bir yolu vardır, ama ben onsuz istiyorum.

2. Belki işaretçilerle bu şekilde çalışmıyorum, ama ya sürekli bir sızıntı alıyorum ya da ana işin devam ettiği blokta işaretçilere vurmam gerekiyor.

Her şey mevcut ... yukarıdaki mesajım
 
equivalent23 :

Bir örnek alabilir miyim?

Sadece verdiğim örnek dökümantasyondan alınmış ve nasıl çalışması gerektiği net değil..

İşte böyle çalışır. Ama belgelere göre hiç de değil :/ (Ama bir kez daha işaretçiler üzerinde çalıştım)

 #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 :

Yapmak:

sanallaştırma ile çok daha kolay hale getirilebilir:


Bundan bahsetmiyorum. Bu, yalnızca işaretçiler kullanmakla ilgili değil, temel sınıf türüne sahip bu işaretçilerin bir dizisidir.

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

Basit bir dizi mi yoksa bir dizi işaretçi mi çalıştığı önemli değildir ve yalnızca temel sınıfta yazılanlar kullanılabilir.

Ya ben bir şey anlamadım.

Örneğin, biraz değiştirilmiş bir temel sınıf (yapı olarak biçimlendirilmiş)

 //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 ); } // возвращает площадь фигуры

};

Bütün bunları böyle bir diziye doldurursak, en azından temel sınıfta bildirilen işlevselliğe erişeceğiz.

Soru, dizi temel sınıf türündeyse (yani dizi CShape türündeyse) alt işlevselliğe nasıl erişileceğidir?

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

Bundan bahsetmiyorum. Bu, yalnızcaişaretçiler kullanmakla ilgili değil, temel sınıf türüne sahip bu işaretçilerin bir dizisidir.

Soru, dizi temel sınıf türündeyse (yani dizi CShape türündeyse) alt işlevselliğe nasıl erişileceğidir?

Son sayfaya şöyle yazdım:

 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;
  }
 

Aynı kod, yalnızca bir diziyle:

 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 :

İşte böyle çalışır. Ama belgelere göre hiç de değil :/

Eh, aslında aynı şeyden bahsediyorum, en azından temel sınıftaki tüm işlevleri belirlemek gerekiyor (aksi takdirde bunlara erişim olmayacak).
 
AlexSTAL :

Yapmak:

İşte bunun için:

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

klavyeye el konulması ile ellerin koparılması gerekir.

C++'da, dynamic_cast'i kullanarak sınıf hiyerarşisinde ilerleyebilirsiniz ve bu arada, orayı da sevmiyorlar. MQL'de bu, örtük çökmelere neden olabilir, bug başka yerde.

Bu nedenle, kategorik olarak böyle bir oyuncu kadrosu kullanmanızı önermiyorum. Yani genel olarak. Atalara lütfen, ne çocuklara.

 
TheXpert :

İşte bunun için:

klavyeye el konulması ile ellerin koparılması gerekir.

C++'da, dynamic_cast'i kullanarak sınıf hiyerarşisinde ilerleyebilirsiniz ve bu arada, orayı da sevmiyorlar. MQL'de bu, örtük çökmelere neden olabilir, bug başka yerde.

Bu nedenle, kategorik olarak böyle bir oyuncu kadrosu kullanmanızı önermiyorum. Yani genel olarak. Atalara lütfen, ne çocuklara.

Nasıl yumuşak cevap verilir ....

Bir programcının kafası kötüyse, o zaman basit bir 1 + 1 işlemi örtük çökmelere neden olabilir ....

Ve MQL5'in C++ olmadığını not etmek istiyorum...

Bu sadece bir olasılık, bir uygulama meselesi değil....

 
AlexSTAL :

Aynı kod, yalnızca bir diziyle:


1. m_radius() öğesini atadan kaldırın, örnekte yoktur. :) Ve OnStart()'ta onunla hiçbir iş yapma;

2. Silme Base[0] satırını başka bir yere taşıyabilir misiniz? Diyelim ki bu bir komut dosyası değil, bir baykuş ise ve dizideki veriler yine de benim için faydalı olacak.

Hemen bir bellek sızıntısı alıyorum. Bu sebeple yapılara geçmek zorunda kaldım...

 
Interesting :

1. m_radius() öğesini kaldırın, örnekte yok. Ve OnStart()'ta onunla hiçbir iş yapmayın;

2. Silme Base[0] satırını başka bir yere taşıyabilir misiniz? Diyelim ki bu bir komut dosyası değil, bir baykuş ise ve dizideki veriler yine de benim için faydalı olacak.

Hemen bir bellek sızıntısı alıyorum. Bu sebeple yapılara geçmek zorunda kaldım...

1) Kaldırıldı, çalışıyor:

 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) Asıl mesele program bitmeden silinmektir... ama bu pointer'ı bir fonksiyonda oluşturduysanız, global bir yere kaydetmeye özen göstermeniz gerekir...