OOP(객체 지향 프로그래밍)에 대한 질문 - 페이지 10

 

매개변수 이름은 중요하지 않습니다.. 뭔가를 혼동하지 않도록 다른 이름이 의미가 있습니다.

함수 선언에는 값만 쓸 수 있습니다.

 public :
   void               SetName( string n);

그러나 기능 자체에서 다른

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

그러나 매개변수의 이름은 어디에서나 동일하게 지정할 수 있습니다. 이것이 코드 작성자에게 더 편리한 방법입니다.

 

같은 튜토리얼에서 코드를 얻었습니다.

 #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 );         // ошибка, закрытый метод базового класса не доступен в потомках

생성자의 이상한 순간:

 public :               //--- конструктор класса доступен всем
                     CBaseClass(){m_member= 5 ; return ;};
여기에 반품 내역 이 있는 이유는 무엇입니까?

생성자에서 이 연산자가 사용되는 것을 본 것은 이번이 처음입니다. 결국 생성자는 자동으로 호출됩니다. 그리고 탈출구가 있을 것입니다. 생성자에서 이 연산자에 의미가 있습니까?

 
hoz :

같은 튜토리얼에서 코드를 얻었습니다.

생성자의 이상한 순간:

여기에 반품 내역 이 있는 이유는 무엇입니까?

이 연산자가 생성자에서 사용되는 것을 본 것은 이번이 처음입니다. 결국 생성자는 자동으로 호출됩니다. 그리고 탈출구가 있을 것입니다. 생성자에서 이 연산자에 의미가 있습니까?

이 예에서는 필요하지 않지만 조기 종료가 필요한 경우 복잡한 초기화가 가능합니다.

생성자와 소멸자는 일반적인 함수입니다. 기본 생성자와 소멸자만 자동으로 호출됩니다. 나머지는 사용자가 호출합니다.

 

교과서는 다형성과 관련하여 이 예를 제공합니다.

 //--- Базовый класс
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);} //площадь квадрата
  };

한 가지를 이해하지 못했습니다. 호출에 여전히 자식 함수 개체를 사용하는 경우, 즉 파생 메서드 CCircleCSquare , GetArea() 영역은 기본 클래스의 선언을 우회하여 계산할 수 있습니다. 저것들. 기본 클래스에서는 가상 함수 를 전혀 생성하지 않고 파생물에서는 일반 메서드를 생성하면 됩니다! 그렇다면 왜 가상 기능이 필요한가?

가상 기능이 일부 이점을 제공한다는 것이 분명한 적절하고 논리적인 예를 보는 것은 흥미롭습니다. 내가 본 것이 논리적이지 않기 때문에 적어도 나에게는. 어쨌든 이해하고 싶습니다.

 
hoz :

교과서는 다형성과 관련하여 이 예를 제공합니다.

한 가지를 이해하지 못했습니다. 호출에 여전히 자식 함수 개체를 사용하는 경우, 즉 파생 메서드 CCircleCSquare , GetArea() 영역은 기본 클래스의 선언을 우회하여 계산할 수 있습니다. 저것들. 기본 클래스에서는 가상 함수를 전혀 생성하지 않고 파생물에서는 일반 메서드를 생성하면 됩니다! 그렇다면 왜 가상 기능이 필요한가?

가상 기능이 일부 이점을 제공한다는 것이 분명한 적절하고 논리적인 예를 보는 것은 흥미롭습니다. 내가 본 것이 논리적이지 않기 때문입니다. 적어도 저에게는 그렇습니다. 어쨌든 이해하고 싶습니다.

이것은 다형성을 이해하는 가장 간단한 예입니다. 빨리 도착하기 위해.

어려운 경우가 있습니다. 필요시 신청하세요. 이제 귀찮게 할 필요가 없습니다. 일이 있을 것이고, 그러면 생각해야 합니다.

예를 들어, 가능한 모든 읽기/쓰기 인터페이스가 있는 기본 클래스가 있습니다. 또한 기본 클래스의 이 인터페이스를 파생 클래스 와 연결하는 개인 가상 메서드(2개만 읽기/쓰기)가 있습니다. 실제로 파생 클래스는 파일(파일, 매핑, 채널, 인터넷) 작업이 있는 모든 위치에 있을 수 있습니다. 각 파생 클래스는 이러한 가상 메서드를 다르게 정의하지만 모든 클래스는 기본 클래스와 동일한 인터페이스를 공유합니다.

 
hoz :

교과서는 다형성과 관련하여 이 예를 제공합니다.

한 가지를 이해하지 못했습니다. 호출에 여전히 자식 함수 개체를 사용하는 경우, 즉 파생 메서드 CCircleCSquare , GetArea() 영역은 기본 클래스의 선언을 우회하여 계산할 수 있습니다. 저것들. 기본 클래스에서는 가상 함수를 전혀 생성하지 않고 파생물에서는 일반 메서드를 생성하면 됩니다! 그렇다면 왜 가상 기능이 필요한가?

가상 기능이 일부 이점을 제공한다는 것이 분명한 적절하고 논리적인 예를 보는 것은 흥미롭습니다. 내가 본 것이 논리적이지 않기 때문입니다. 적어도 저에게는 그렇습니다. 어쨌든 이해하고 싶습니다.

작은 예를 스케치해 보겠습니다.

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

이 구조 덕분에 추가 개선이 가능하므로 작업 알고리즘에 들어갈 필요가 없습니다. 이 알고리즘은 매우 크고 복잡할 수 있습니다(여기서 모든 것이 단순화됨). 우리는 하나의 후속 작업인 m3를 열거형에 추가하고 하나를 추가하기만 하면 됩니다. 스위치의 경우가 더 많습니다. 저것들. 프로그램의 주요 부분에서 편집을 피할 수 있도록 입력 데이터를 통합했습니다.

물론 이것은 작업 알고리즘이 다양한 유형을 입력으로 받아들이는 경우에만 관련이 있습니다. 유형이 하나라면 이 모든 것이 쓸모가 없습니다.

 
hoz :

교과서는 다형성과 관련하여 이 예를 제공합니다.

한 가지를 이해하지 못했습니다. 호출에 여전히 자식 함수 개체를 사용하는 경우, 즉 파생 메서드 CCircleCSquare , GetArea() 영역은 기본 클래스의 선언을 우회하여 계산할 수 있습니다. 저것들. 기본 클래스에서는 가상 함수를 전혀 생성하지 않고 파생물에서는 일반 메서드를 생성하면 됩니다! 그렇다면 왜 가상 기능이 필요한가?

가상 기능이 일부 이점을 제공한다는 것이 분명한 적절하고 논리적인 예를 보는 것은 흥미롭습니다. 내가 본 것이 논리적이지 않기 때문입니다. 적어도 저에게는 그렇습니다. 어쨌든 이해하고 싶습니다.

다음은 간단한 예입니다.

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() 함수를 사용합니다.
 

수업에 이 세터가 있습니다.

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

컴파일러는 일반적으로 다음과 같이 ColorBySend 배열 에 요소를 할당하는 것에 대해 맹세합니다.

'fc_ColorSendBuy' - constant expression required        TradingFunc.mqh 91      23
'fc_ColorSendSell' - constant expression required       TradingFunc.mqh 91      40
'{' - expression expected       TradingFunc.mqh 91      22
그것은 무엇과 연결되어 있습니까? 요소별로 값을 할당해야 합니까? 목록이 불가능합니까? 그것은 무엇과 연결되어 있습니까? 결국 교과서에서도 과제가 이렇게 나오다니...
 
hoz :

수업에 그런 Setter가 있습니다.

컴파일러는 일반적으로 다음과 같이 ColorBySend 배열에 요소를 할당하는 것에 대해 맹세합니다.

그것은 무엇과 연결되어 있습니까? 요소별로 값을 할당해야 합니까? 목록이 불가능합니까? 그것은 무엇과 연결되어 있습니까? 결국 교과서에서도 과제가 이렇게 나오다니...


{something, something other}와 같은 구성은 상수의 배열일 수 있습니다. 본질적으로 함수의 지역 변수 인 함수에 전달된 매개변수가 있습니다. const 수정자는 전달된 값을 수정할 수 없음을 나타내기 때문에 이 경우 중요하지 않습니다. 결국
{fc_ColorSendBuy, fc_ColorSendSell}
컴파일러가 이해할 수 없는 변수 표현식입니다. 아아.
 
목록 초기화는 선언된 경우에만 가능합니다.