OOP (Nesneye Yönelik Programlama) hakkında sorular - sayfa 10

 

parametre adları önemli değil.. farklı isimler bir şeyi bir şeyle karıştırmamak için mantıklı..

fonksiyon bildiriminde sadece değerleri yazabilirsiniz,

 public :
   void               SetName( string n);

ama işlevin kendisinde diğerleri

 void CPerson::SetName( string nnn)
  {
   m_name.first_name=GetFirstName(nnn);
   m_name.last_name=GetLastName(nnn);
  }

ancak parametreleri her yerde aynı şekilde adlandırabilirsiniz, kod yazıcısı için bu şekilde daha uygun olur

 

Aynı eğitimde kodu aldım:

 #property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
//+------------------------------------------------------------------+
//| Класс-пример с несколькими типами доступа                        |
//+------------------------------------------------------------------+
class CBaseClass
  {
private :             //--- закрытый член недоступен из потомков
   int                m_member;
protected :           //--- защищенный метод доступен из базового класса и его потомков
   int                Member(){ return (m_member);}
public :               //--- конструктор класса доступен всем
                     CBaseClass(){m_member= 5 ; return ;};
private :             //--- закрытый метод для присвоения значения члену m_member
   void               Member( int value) { m_member=value;};
  };
//+------------------------------------------------------------------+
//| Производный класс с ошибками                                     |
//+------------------------------------------------------------------+
class CDerived: public CBaseClass // public наследование можно не указывать, оно по умолчанию
  {
public :
   void Func() // определим в потомке функцию с обращениями к членам базового класса 
     {
       //--- попытка модификации закрытого члена базового класса
      m_member= 0 ;         // ошибка, закрытый член базового класса никому не доступен
      Member( 0 );         // ошибка, закрытый метод базового класса не доступен в потомках

Yapıcıdaki garip an:

 public :               //--- конструктор класса доступен всем
                     CBaseClass(){m_member= 5 ; return ;};
Neden burada bir iade ifadesi var?

Bu operatörün bir kurucuda kullanıldığını ilk defa görüyorum. Sonuçta, aslında yapıcı otomatik olarak çağrılır. Ve bir çıkış yolu olacak. Yapıcıda bu operatörde bir anlam var mı?

 
hoz :

Aynı öğreticide kodu aldım:

Yapıcıdaki garip an:

Neden burada bir iade ifadesi var?

Bu operatörün bir kurucuda kullanıldığını ilk kez görüyorum. Sonuçta, aslında, yapıcı otomatik olarak çağrılır. Ve bir çıkış yolu olacak. Bu operatörün yapıcıda bir anlamı var mı?

Bu örnekte gerekli değildir, ancak erken bir çıkış gerektiğinde karmaşık başlatma mümkündür.

Yapıcı ve yıkıcı normal fonksiyonlardır. Yalnızca varsayılan kurucu ve yıkıcı otomatik olarak çağrılır. Kullanıcının aradığı geri kalanı.

 

Ders kitabı bu örneği polimorfizmle ilgili olarak verir:

 //--- Базовый класс
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
   double         GetArea(){ return ( 0 ); } // возвращает площадь фигуры
  };
 //--- производный класс Круг
class CCircle : public CShape            // после двоеточия указывается базовый класс,
  {                                      // от которого производится наследование 
private :
   double         m_radius;              // радиус круга
public :
   void           CCircle(){m_type= 1 ;};  // конструктор, тип равен 1 
   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 
   void            SetSide( double s){m_square_side=s;};
   virtual double  GetArea(){ return (m_square_side*m_square_side);} //площадь квадрата
  };

Bir şeyi anlamadım. Çağrılar için hala alt işlev nesneleri kullanıyorsanız, ör. türetilmiş yöntemler CCircle ve CSquare , ardından GetArea() alanı, temel sınıftaki bildirimleri atlayarak hesaplanabilir. Onlar. temel sınıfta hiç sanal işlevler oluşturmayın, türevlerde normal bir yöntem oluşturun ve hepsi bu kadar! O zaman neden sanal bir işleve ihtiyaç var?

Sanal işlevlerin bir miktar fayda sağladığının açık olduğu yeterli ve mantıklı bir örnek görmek ilginçtir. Çünkü gördüklerim mantıklı değil, en azından benim için. neyse anlamak isterim.

 
hoz :

Ders kitabı bu örneği polimorfizmle ilgili olarak verir:

Bir şeyi anlamadım. Çağrılar için hala alt işlev nesneleri kullanıyorsanız, ör. türetilmiş yöntemler CCircle ve CSquare , ardından GetArea() alanı, temel sınıftaki bildirimleri atlayarak hesaplanabilir. Onlar. temel sınıfta hiç sanal işlevler oluşturmayın, türevlerde normal bir yöntem oluşturun ve hepsi bu kadar! O zaman neden sanal bir işleve ihtiyaç var?

Sanal işlevlerin bir miktar fayda sağladığının açık olduğu yeterli ve mantıklı bir örnek görmek ilginçtir. Çünkü gördüklerim mantıklı değil, en azından benim için. neyse anlamak isterim.

Bu, polimorfizmi anlamak için en basit örnektir. Oraya çabuk ulaşmak için.

Zor durumlar var. Gerektiğinde başvurun. Şimdi uğraşmanın bir anlamı yok. Bir görev olacak, o zaman düşünmelisin.

Örneğin, tüm olası okuma/yazma arayüzlerine sahip bir temel sınıfım var. Ayrıca temel sınıftaki bu arabirimi türetilmiş sınıflara bağlayan özel sanal yöntemlere (yalnızca 2-okuma/yazma) sahiptir. Aslında, türetilmiş sınıflar, dosyalarla çalışmanın olduğu herhangi bir yerde olabilir (dosyalar, haritalama, kanallar, İnternet). Türetilmiş sınıfların her biri bu sanal yöntemleri farklı şekilde tanımlar, ancak tüm sınıflar temel sınıftan aynı arabirimi paylaşır.

 
hoz :

Ders kitabı bu örneği polimorfizmle ilgili olarak verir:

Bir şeyi anlamadım. Çağrılar için hala alt işlev nesneleri kullanıyorsanız, ör. türetilmiş yöntemler CCircle ve CSquare , ardından GetArea() alanı, temel sınıftaki bildirimleri atlayarak hesaplanabilir. Onlar. temel sınıfta hiç sanal işlevler oluşturmayın, türevlerde normal bir yöntem oluşturun ve hepsi bu kadar! O zaman neden sanal bir işleve ihtiyaç var?

Sanal işlevlerin bir miktar fayda sağladığının açık olduğu yeterli ve mantıklı bir örnek görmek ilginçtir. Çünkü gördüklerim mantıklı değil, en azından benim için. neyse anlamak isterim.

Küçük bir örnek çizmeye çalışacağım:

 #property strict
#property show_inputs

enum Mes_type {
    m1,
    m2
};
input Mes_type mes_t;   // Выберите тип сообщения

class Message {
public :
     virtual void action() {};
};

class Mes1 : public Message {
public :
     virtual void action() { Alert ( "Типичные ошибки в программах" );}
};

class Mes2 : public Message {
public :
     virtual void action() { Alert ( "Оффлайновые графики" );}
};

void OnStart () {
     // Формируем входные данные для какого-то алгоритма
     //////////////////////////////////////////
    Message *mes;                           //
     switch (mes_t)                           //
    {                                       //
         case m1:                             //
            mes = new Mes1;                 //
             break ;                           //
         case m2:                             //
            mes = new Mes2;                 //
    }                                       //
     /////////////////////////////////////////
    
     // Рабочий алгоритм
     //////////////////////////////////////////
    mes.action();                           //
     //////////////////////////////////////////
  
     delete mes;
}

Bu yapı sayesinde, olası iyileştirmelerle, çok büyük ve karmaşık olabilen çalışma algoritmasına girmemize gerek yok (burada her şey basitleştirilmiştir), sadece bir ardıl, numaralandırmada m3 ve bir tane daha eklememiz gerekiyor. Anahtarda daha fazla durum. Onlar. Programın ana bölümünde düzenleme yapmaktan kaçınmamıza izin verecek giriş verilerini birleştirdik.

Tabii ki, bu yalnızca çalışma algoritmasının çeşitli türleri girdi olarak kabul etmesi durumunda geçerlidir. Tür bir ise, tüm bunlar işe yaramaz.

 
hoz :

Ders kitabı bu örneği polimorfizmle ilgili olarak verir:

Bir şeyi anlamadım. Çağrılar için hala alt işlev nesneleri kullanıyorsanız, ör. türetilmiş yöntemler CCircle ve CSquare , ardından GetArea() alanı, temel sınıftaki bildirimleri atlayarak hesaplanabilir. Onlar. temel sınıfta hiç sanal işlevler oluşturmayın, türevlerde normal bir yöntem oluşturun ve hepsi bu kadar! O zaman neden sanal bir işleve ihtiyaç var?

Sanal işlevlerin bir miktar fayda sağladığının açık olduğu yeterli ve mantıklı bir örnek görmek ilginçtir. Çünkü gördüklerim mantıklı değil, en azından benim için. neyse anlamak isterim.

İşte basit bir örnek:

CShape* GetNewShape()
{
         if ( ... ) // Здесь какое-то условие.
                return new CCircle();
         else
                 return new CSquare();
}

CShape* M[ 10 ];

for ( int i = 0 ; i < 10 ; i++ )
{
        M[i] = GetNewShape();
}


double WholeArea = 0.0 ;
for ( int i = 0 ; i < 10 ; i++ )
{
        WholeArea += M[i].GetArea();
}
GetArea() işlevini, hangi şekle çağrıldığını bilmeden kullanırız.
 

Sınıfta bu ayarlayıcı var:

 //---- SetColorBySend
TradingFunc::SetColorBySend ( const color fc_ColorSendBuy,      // Цвет открытия ордера на покупку
                             const color fc_ColorSendSell)     // Цвет открытия ордера на продажу
{
   ColorBySend [ 2 ] = {fc_ColorSendBuy, fc_ColorSendSell};
}

Derleyici, ColorBySend dizisine böyle bir öğe ataması hakkında genel olarak şu şekilde yemin eder:

'fc_ColorSendBuy' - constant expression required        TradingFunc.mqh 91      23
'fc_ColorSendSell' - constant expression required       TradingFunc.mqh 91      40
'{' - expression expected       TradingFunc.mqh 91      22
Neyle bağlantılı? Değerleri öğeye öğeye atamak gerçekten gerekli mi? Liste mümkün değil mi? Neyle bağlantılı? Sonuçta, ders kitabında bile atama böyle gerçekleşir ...
 
hoz :

Sınıfta bu ayarlayıcı var:

Derleyici, ColorBySend dizisine böyle bir öğe ataması hakkında genel olarak şu şekilde yemin eder:

Neyle bağlantılı? Değerleri öğeye öğeye atamak gerçekten gerekli mi? Liste mümkün değil mi? Neyle bağlantılı? Sonuçta, ders kitabında bile atama böyle gerçekleşir ...


{bir şey, başka bir şey} gibi bir yapı yalnızca bir dizi sabit olabilir. Esasen işlevin yerel değişkenleri olan, işleve geçirilen parametreleri orada değiştirmişsinizdir. Bu durumda const değiştiricisi önemli değildir, çünkü yalnızca iletilen değerin değiştirilemeyeceğini belirtir. Sonuçta
{fc_ColorSendBuy, fc_ColorSendSell}
derleyicinin anlayamadığı değişken bir ifadedir. Ne yazık ki.
 
Liste başlatma yalnızca bildirildiğinde mümkündür.
Neden: