#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_membervoid Member(int value) { m_member=value;};
};
//+------------------------------------------------------------------+//| Производный класс с ошибками |//+------------------------------------------------------------------+class CDerived: public CBaseClass // public наследование можно не указывать, оно по умолчанию
{
public:
void Func() // определим в потомке функцию с обращениями к членам базового класса
{
//--- попытка модификации закрытого члена базового класса
m_member=0; // ошибка, закрытый член базового класса никому не доступен
Member(0); // ошибка, закрытый метод базового класса не доступен в потомках
Coisa estranha sobre o construtor:
public: //--- конструктор класса доступен всем
CBaseClass(){m_member=5;return;};
Por que há um operador de retorno aqui?
Esta é a primeira vez que vejo este operador ser utilizado na construtora. Na verdade, o construtor é chamado automaticamente. E haverá uma saída de qualquer maneira. Este operador faz sentido no construtor?
Esta é a primeira vez que vejo este operador ser utilizado na construtora. Na verdade, o construtor é chamado automaticamente. E haverá uma saída de qualquer maneira. Este operador faz sentido no construtor?
Não é necessário neste exemplo, mas pode haver uma inicialização complexa quando é necessária uma saída antecipada.
O construtor e o destruidor são funções normais. Somente o construtor e o destruidor padrão são chamados automaticamente. Os outros são chamados pelo usuário.
O livro didático dá este exemplo em relação ao polimorfismo:
//--- Базовый класс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);};// возвращает тип фигурыvirtualdouble 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;};
virtualdouble 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;};
virtualdouble GetArea(){return (m_square_side*m_square_side);}//площадь квадрата
};
Há uma coisa que eu não entendo. Se utilizarmos objetos de função infantil para chamadas, ou seja, métodos derivados CCircle e CSquare, então a área GetArea() pode ser calculada contornando declarações em classe base. Isto é, não criar funções virtuais na classe base e nos métodos derivados criar um método simples e pronto! Então, por que precisamos de uma função virtual?
É interessante ver um exemplo adequado e lógico, onde você pode ver que as funções virtuais proporcionam algum benefício. Porque o que eu vi não era lógico, pelo menos para mim. Eu gostaria de entender tudo da mesma forma.
O livro didático dá este exemplo em relação ao polimorfismo:
Há uma coisa que eu não entendo. Se usarmos objetos de função infantil para chamadas, ou seja, métodos derivados CCircle e CSquare, então a área GetArea() pode ser calculada contornando declarações em classe base. Isto é, não criar funções virtuais em uma classe base, e em métodos derivados criar um método simples e pronto! Então, por que precisamos de uma função virtual?
É interessante ver um exemplo adequado e lógico, onde você pode ver que as funções virtuais proporcionam algum benefício. Porque o que eu vi não era lógico, pelo menos para mim. Eu gostaria de entender tudo da mesma forma.
Esta é a amostra mais simples para entender o polimorfismo. Para obtê-lo rapidamente.
Há casos complicados. Você a aplicará quando precisar dela. Não faz sentido se preocupar agora. Quando a tarefa estiver concluída, você terá que pensar sobre isso.
Por exemplo, tenho uma classe base com todas as interfaces de leitura/escrita possíveis. Possui também métodos virtuais privados (2 no total - leitura/escrita), que ligam esta interface na classe base com classes derivadas. Na verdade, as classes derivadas podem ser qualquer uma onde haja trabalho com arquivos (arquivos, mapeamento, canais, internet). Cada uma das classes derivadas define estes métodos virtuais de forma diferente, mas todas as classes têm a mesma interface da classe base.
O livro didático dá este exemplo em relação ao polimorfismo:
Há uma coisa que eu não entendo. Se usarmos objetos de função infantil para chamadas, ou seja, métodos derivados CCircle e CSquare, então a área GetArea() pode ser calculada contornando declarações em classe base. Isto é, não criar funções virtuais na classe base e nos métodos derivados criar um método simples e pronto! Então, por que precisamos de uma função virtual?
É interessante ver um exemplo adequado e lógico, onde você pode ver que as funções virtuais proporcionam algum benefício. Porque o que eu vi não era lógico, pelo menos para mim. Quero entender tudo da mesma forma.
Vou tentar esboçar uma pequena amostra:
#property strict#property show_inputsenum Mes_type {
m1,
m2
};
input Mes_type mes_t; // Выберите тип сообщенияclass Message {
public:
virtualvoid action() {};
};
class Mes1 : public Message {
public:
virtualvoid action() {Alert("Типичные ошибки в программах");}
};
class Mes2 : public Message {
public:
virtualvoid action() {Alert("Оффлайновые графики");}
};
voidOnStart() {
// Формируем входные данные для какого-то алгоритма//////////////////////////////////////////
Message *mes; //switch(mes_t) //
{ //case m1: //
mes = new Mes1; //break; //case m2: //
mes = new Mes2; //
} ///////////////////////////////////////////// Рабочий алгоритм//////////////////////////////////////////
mes.action(); ////////////////////////////////////////////delete mes;
}
Graças a esta estrutura, não precisaremos entrar em algoritmo de trabalho, que pode ser muito grande e complexo (tudo é simplificado aqui), precisaremos apenas adicionar mais um descendente, m3 na enumeração e mais um caso no switch. Ou seja, unificamos os dados de entrada, o que evitará a edição na parte principal do programa.
Naturalmente, isto só será apropriado se o algoritmo de trabalho aceitar uma variedade de tipos como entrada. Se existe apenas um tipo, tudo isso é inútil.
O livro didático dá este exemplo em relação ao polimorfismo:
Há uma coisa que eu não entendo. Se utilizarmos objetos de função infantil para chamadas, ou seja, métodos derivados CCircle e CSquare, então a área GetArea() pode ser calculada contornando declarações em classe base. Isto é, não criar funções virtuais na classe base e nos métodos derivados criar um método simples e pronto! Então, por que precisamos de uma função virtual?
É interessante ver um exemplo adequado e lógico, onde você pode ver que as funções virtuais proporcionam algum benefício. Porque o que eu vi não era lógico, pelo menos para mim. Eu gostaria de entender tudo da mesma forma.
Aqui está um exemplo simples:
CShape* GetNewShape()
{
if( ... ) // Здесь какое-то условие.
returnnew CCircle();
elsereturnnew 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();
}
Usamos a função GetArea() sem saber qual a forma a que ela é chamada.
//---- SetColorBySend
TradingFunc::SetColorBySend (constcolor fc_ColorSendBuy, // Цвет открытия ордера на покупкуconstcolor fc_ColorSendSell) // Цвет открытия ордера на продажу
{
ColorBySend [2] = {fc_ColorSendBuy, fc_ColorSendSell};
}
O compilador está geralmente combatendo esta atribuição de elementos para a matrizColorBySend desta forma:
O que isso tem a ver? É realmente necessário atribuir valores elemento por elemento? Não é possível fazer isso como uma lista? A que está relacionado? Afinal, é assim que a tarefa é feita, mesmo no livro didático.
O compilador jura a esta atribuição de elementos para a matriz ColorBySend em geral assim:
O que isso tem a ver? É realmente necessário atribuir valores elemento por elemento? Não é possível fazer isso como uma lista? O que tem a ver com isso? Afinal, é assim que a tarefa é feita, mesmo no livro didático.
Uma construção do tipo {something, something else} só pode ser um conjunto de constantes. Mas os parâmetros passados para a função são ali substituídos que são realmente variáveis locais da função. O modificador const neste caso não tem significado, pois apenas indica que o valor passado não pode ser modificado. Como resultado,
{fc_ColorSendBuy, fc_ColorSendSell}
é uma expressão variável que o compilador não consegue entender. Ai de mim.
nomes de parâmetros não são importantes... nomes diferentes fazem sentido para que algo não seja confundido com algo...
Você pode escrever alguns valores na declaração de função,
e outros valores na própria função
ou você pode nomear os parâmetros de forma idêntica em todos os lugares, o que for mais conveniente para o codificador
No mesmo livro didático, o código se deparou:
Coisa estranha sobre o construtor:
Por que há um operador de retorno aqui?Esta é a primeira vez que vejo este operador ser utilizado na construtora. Na verdade, o construtor é chamado automaticamente. E haverá uma saída de qualquer maneira. Este operador faz sentido no construtor?
No mesmo livro didático, o código se deparou:
Coisa estranha sobre o construtor:
Por que existe aqui um operador de retorno?Esta é a primeira vez que vejo este operador ser utilizado na construtora. Na verdade, o construtor é chamado automaticamente. E haverá uma saída de qualquer maneira. Este operador faz sentido no construtor?
Não é necessário neste exemplo, mas pode haver uma inicialização complexa quando é necessária uma saída antecipada.
O construtor e o destruidor são funções normais. Somente o construtor e o destruidor padrão são chamados automaticamente. Os outros são chamados pelo usuário.
O livro didático dá este exemplo em relação ao polimorfismo:
Há uma coisa que eu não entendo. Se utilizarmos objetos de função infantil para chamadas, ou seja, métodos derivados CCircle e CSquare, então a área GetArea() pode ser calculada contornando declarações em classe base. Isto é, não criar funções virtuais na classe base e nos métodos derivados criar um método simples e pronto! Então, por que precisamos de uma função virtual?
É interessante ver um exemplo adequado e lógico, onde você pode ver que as funções virtuais proporcionam algum benefício. Porque o que eu vi não era lógico, pelo menos para mim. Eu gostaria de entender tudo da mesma forma.
O livro didático dá este exemplo em relação ao polimorfismo:
Há uma coisa que eu não entendo. Se usarmos objetos de função infantil para chamadas, ou seja, métodos derivados CCircle e CSquare, então a área GetArea() pode ser calculada contornando declarações em classe base. Isto é, não criar funções virtuais em uma classe base, e em métodos derivados criar um método simples e pronto! Então, por que precisamos de uma função virtual?
É interessante ver um exemplo adequado e lógico, onde você pode ver que as funções virtuais proporcionam algum benefício. Porque o que eu vi não era lógico, pelo menos para mim. Eu gostaria de entender tudo da mesma forma.
Esta é a amostra mais simples para entender o polimorfismo. Para obtê-lo rapidamente.
Há casos complicados. Você a aplicará quando precisar dela. Não faz sentido se preocupar agora. Quando a tarefa estiver concluída, você terá que pensar sobre isso.
Por exemplo, tenho uma classe base com todas as interfaces de leitura/escrita possíveis. Possui também métodos virtuais privados (2 no total - leitura/escrita), que ligam esta interface na classe base com classes derivadas. Na verdade, as classes derivadas podem ser qualquer uma onde haja trabalho com arquivos (arquivos, mapeamento, canais, internet). Cada uma das classes derivadas define estes métodos virtuais de forma diferente, mas todas as classes têm a mesma interface da classe base.
O livro didático dá este exemplo em relação ao polimorfismo:
Há uma coisa que eu não entendo. Se usarmos objetos de função infantil para chamadas, ou seja, métodos derivados CCircle e CSquare, então a área GetArea() pode ser calculada contornando declarações em classe base. Isto é, não criar funções virtuais na classe base e nos métodos derivados criar um método simples e pronto! Então, por que precisamos de uma função virtual?
É interessante ver um exemplo adequado e lógico, onde você pode ver que as funções virtuais proporcionam algum benefício. Porque o que eu vi não era lógico, pelo menos para mim. Quero entender tudo da mesma forma.
Vou tentar esboçar uma pequena amostra:
Graças a esta estrutura, não precisaremos entrar em algoritmo de trabalho, que pode ser muito grande e complexo (tudo é simplificado aqui), precisaremos apenas adicionar mais um descendente, m3 na enumeração e mais um caso no switch. Ou seja, unificamos os dados de entrada, o que evitará a edição na parte principal do programa.
Naturalmente, isto só será apropriado se o algoritmo de trabalho aceitar uma variedade de tipos como entrada. Se existe apenas um tipo, tudo isso é inútil.
O livro didático dá este exemplo em relação ao polimorfismo:
Há uma coisa que eu não entendo. Se utilizarmos objetos de função infantil para chamadas, ou seja, métodos derivados CCircle e CSquare, então a área GetArea() pode ser calculada contornando declarações em classe base. Isto é, não criar funções virtuais na classe base e nos métodos derivados criar um método simples e pronto! Então, por que precisamos de uma função virtual?
É interessante ver um exemplo adequado e lógico, onde você pode ver que as funções virtuais proporcionam algum benefício. Porque o que eu vi não era lógico, pelo menos para mim. Eu gostaria de entender tudo da mesma forma.
Aqui está um exemplo simples:
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(); }Usamos a função GetArea() sem saber qual a forma a que ela é chamada.Eu tenho este setter em uma classe:
O compilador está geralmente combatendo esta atribuição de elementos para a matriz ColorBySend desta forma:
'fc_ColorSendBuy' - constant expression required TradingFunc.mqh 91 23 'fc_ColorSendSell' - constant expression required TradingFunc.mqh 91 40 '{' - expression expected TradingFunc.mqh 91 22O que isso tem a ver? É realmente necessário atribuir valores elemento por elemento? Não é possível fazer isso como uma lista? A que está relacionado? Afinal, é assim que a tarefa é feita, mesmo no livro didático.Eu tenho este setter em uma classe:
O compilador jura a esta atribuição de elementos para a matriz ColorBySend em geral assim:
O que isso tem a ver? É realmente necessário atribuir valores elemento por elemento? Não é possível fazer isso como uma lista? O que tem a ver com isso? Afinal, é assim que a tarefa é feita, mesmo no livro didático.{fc_ColorSendBuy, fc_ColorSendSell}é uma expressão variável que o compilador não consegue entender. Ai de mim.