Perguntas OOP (Object Oriented Programming) - página 9

 
Integer:

Isto significa que você tem que criar uma instância utilizando o novo operador.
Há uma coisa que eu não entendo. Quais são as razões convincentes para usar o novo operador? Você não pode fazê-lo sem ele, pode?
 
hoz:
Há uma coisa que eu não entendo. Que boas razões existem para forçar o uso do novo operador? Está tudo bem sem ele?


É necessário se você quiser criar objetos de forma dinâmica. Se você não souber com antecedência quantos objetos e que tipos de objetos serão necessários.

 
hoz:
Так я вот одного не пойму. Какие веские причины принуждают к использованию оператора new ? Без него типа никак?
Inteiro:
É necessário se você precisar criar objetos de forma dinâmica. Se você não sabe com antecedência quantos objetos e que tipos de objetos são necessários,

Você pode usar matrizes de classe dinâmicas. Na MQL isto vai funcionar. Em C++, pode haver problemas com a iniciação de classe dos membros da classe. É por isso que é melhor colocar um ponteiro inteligente na matriz. Assim você não precisa lidar com inicialização de classe e limpeza de memória.

 
mql5:
class cFather
 {
 public:
 int GetData() {return 3;}
 };
 //+------------------------------------------------------------------+
 //| |
 //+------------------------------------------------------------------+
 class cChild : public cFather
 {
 public:
 int GetData() {return 5;}
 };

 int f(cFather *p) {return p.GetData();}
 //+------------------------------------------------------------------+
 //| |
 //+------------------------------------------------------------------+
 int OnStart()
 {
 cChild obj,*ptr=GetPointer(obj);
 f(ptr); // вернет 3
 ((cFather *)ptr).GetData(); // вернет 3

 return 0;
 }

Como esta construção "lê"?

((cFather *)ptr).GetData();

Ah, em particular:

(cFather *)ptr)
Estou olhando para ele e não entendo a essência do que está acontecendo...
 
hoz:

Como esta construção "lê"?

((cFather *)ptr).GetData();

ptr é convertido para tipo cFather(classe) e seumétodo (cFather) GetData() é chamado

algo como isto...

 
keekkenen:

ptr é convertido para tipo cFather(classe) e seumétodo (cFather) GetData() é chamado

algo como isto...

Isso é uma coisa estranha... Pensei que fosse aproximadamente, mas... é demais para ser lançado a um tipo (classe). De qualquer forma, na programação, pelo que ouvi, não é recomendável lançar para um tipo (classe). Mas não é apenas uma conversão de tipo padrão - é uma conversão de classe.

Bem, vamos voltar a este código mais uma vez:

class cFather
 {
 public:
 int GetData() {return 3;}
 };
 //+------------------------------------------------------------------+
 //| |
 //+------------------------------------------------------------------+
 class cChild : public cFather
 {
 public:
 int GetData() {return 5;}
 };

 int f(cFather *p) {return p.GetData();}
 //+------------------------------------------------------------------+
 //| |
 //+------------------------------------------------------------------+
 int OnStart()
 {
 cChild obj,*ptr=GetPointer(obj);
 f(ptr); // вернет 3
 ((cFather *)ptr).GetData(); // вернет 3

 return 0;
 }

Aqui nos parâmetros do protótipo da função f, podemos ver claramente que a função f toma um método da classe cFather em seus parâmetros. Além disso, vemos a seguinte situação no código START:

 f(ptr); // вернет 3

Aqui é onde a função f leva um ponteiro para a classe cChild, em vez de um método da classe cFather. Desde cChild obj, *ptr = GetPointer( obj );

Qual é a lógica por trás disso?

 

mm... lógica onde ?

no método f(), eu acho que a lógica é que o parâmetro de entrada será tratado corretamente para o cFather (ou seus descendentes)

 
keekkenen:

mm... lógica onde ?

no método f(), acho que a lógica é que o parâmetro de entrada será tratado corretamente para o cFather (ou seus descendentes)

Isto é

 int f(cFather *p) {return p.GetData();}

aqui *p é um ponteiro para o cFather?

Ao mesmo tempo, estou estudando C++ e estou um pouco confuso com um vocabulário semelhante. No entanto, os ponteiros não são os mesmos aqui.

 
hoz:

Isto é

aqui *p é um ponteiro para o cFather?

Ao mesmo tempo, estou estudando C++ e estou um pouco confuso com um vocabulário semelhante. No entanto, as indicações aqui não são as mesmas.

cFather é um tipo de ponteiro. A própria variável ponteiro aponta para uma instância da classe.
 

Passaram algumas semanas desde que tive uma pergunta. Eu decidi perguntar. Não é muito complicado, mas, logicamente, estou me perguntando se esta é uma opção. Aqui está o código:

struct Name
  {
   string            first_name;                 // имя
   string            last_name;                  // фамилия
  };
class CPerson
  {
protected:
   Name              m_name;                     // имя
public:
   void              SetName(string n);
   string            GetName(){return(m_name.first_name+" "+m_name.last_name);}
private:
   string            GetFirstName(string full_name);
   string            GetLastName(string full_name);
  };
void CPerson::SetName(string n)
  {
   m_name.first_name=GetFirstName(n);
   m_name.last_name=GetLastName(n);
  }
string CPerson::GetFirstName(string full_name)
  {
   int pos=StringFind(full_name," ");
   if(pos>0) StringSetCharacter(full_name,pos,0);
   return(full_name);
  }
string CPerson::GetLastName(string full_name)
  {
   string ret_string;
   int pos=StringFind(full_name," ");
   if(pos>0) ret_string=StringSubstr(full_name,pos+1);
   else      ret_string=full_name;
   return(ret_string);
  }

Existem apenas 2 funções públicas neste código:

public:
   void              SetName(string n);
   string            GetName(){return(m_name.first_name+" "+m_name.last_name);}

E as 2 funções privadas são chamadas diretamente através da função pública, ou melhor, da função pública, no momento da necessidade. O interessante é que a função void SetName(string n ) tem o parâmetro n, mas ambos os métodos privados: string GetFirstName(string nome_total_nome) e string GetLastName(string nome_total_nome) por alguma razão não têm o mesmo parâmetro. Embora se você pegar este mesmo código (não o outro), os métodos privados são chamados através dos públicos com os mesmos parâmetros e não há outra maneira. Então por que eu deveria dar nomes diferentes aos parâmetros?

Espero que a pergunta seja clara.