Domande su OOP (programmazione orientata agli oggetti) - pagina 9

 
Integer:

Questo significa che dovete creare un'istanza usando l'operatore new.
C'è una cosa che non capisco. Quali sono le ragioni convincenti per utilizzare il nuovo operatore? È impossibile farne a meno?
 
hoz:
C'è una cosa che non capisco. Quali buone ragioni ci sono per forzare l'uso del nuovo operatore? Va bene anche senza?


È necessario se volete creare oggetti dinamicamente. Se non sapete in anticipo quanti oggetti e quali tipi di oggetti saranno necessari.

 
hoz:
Так я вот одного не пойму. Какие веские причины принуждают к использованию оператора new ? Без него типа никак?
Integer:
È necessario se avete bisogno di creare oggetti dinamicamente. Se non sapete in anticipo quanti oggetti e quali tipi di oggetti sono necessari.

Potete usare gli array di classi dinamiche. In MQL questo funzionerà. In C++, ci possono essere problemi con l'inizializzazione dei membri della classe. Ecco perché è meglio mettere un puntatore intelligente nell'array. Così non si ha a che fare con l'inizializzazione delle classi e la cancellazione della memoria.

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

Come si "legge" questa costruzione?

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

Ah, in particolare:

(cFather *)ptr)
Lo sto guardando e non capisco il senso di quello che sta succedendo...
 
hoz:

Come si "legge" questa costruzione?

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

ptr è convertito al tipo cFather(classe) e il suometodo (cFather) GetData() è chiamato

qualcosa del genere...

 
keekkenen:

ptr è convertito al tipo cFather(classe) e il suometodo (cFather) GetData() è chiamato

qualcosa del genere...

È una cosa strana... L'ho pensato all'incirca così, ma... è troppo per essere lanciato su un tipo (classe). Nella programmazione comunque, per quanto ho sentito, non è raccomandato fare il cast a un tipo (classe). Ma non è solo una conversione di tipo standard - è piuttosto una conversione di classe.

Bene, torniamo ancora una volta a questo codice:

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

Qui nei parametri del prototipo della funzione f possiamo vedere chiaramente che la funzione f prende un metodo della classe cFather nei parametri. Inoltre vediamo la seguente situazione nel codice START:

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

Qui la funzione f prende un puntatore alla classe cChild, piuttosto che un metodo della classe cFather. Poiché cChild obj, *ptr = GetPointer( obj );

Qual è la logica dietro questo?

 

mm... logica dove?

nel metodo f(), penso che la logica sia che il parametro in entrata sarà gestito correttamente per cFather (o i suoi discendenti)

 
keekkenen:

mm... logica dove?

nel metodo f(), penso che la logica sia che il parametro in entrata sarà gestito correttamente per cFather (o i suoi successori)

Cioè

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

qui *p è un puntatore a cFather?

Allo stesso tempo, sto studiando C++ e sono un po' confuso da un vocabolario simile. Ipuntatori non sono la stessa cosa qui però.

 
hoz:

Cioè

qui *p è un puntatore a cFather?

Allo stesso tempo, sto studiando C++ e sono un po' confuso da un vocabolario simile. Leindicazioni qui non sono le stesse però.

cFather è un tipo di puntatore. La stessa variabile puntatore punta a un'istanza della classe.
 

Sono passate un paio di settimane da quando ho avuto una domanda. Ho deciso di chiederlo. Non è troppo complicato, ma logicamente mi sto chiedendo se questa è un'opzione. Ecco il codice:

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

Ci sono solo 2 funzioni pubbliche in questo codice:

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

E le 2 funzioni private sono chiamate direttamente attraverso la funzione pubblica, o meglio la funzione pubblica, quando serve. Quello che è interessante è che la funzione void SetName(string n) ha il parametro n, ma entrambi i metodi privati: string GetFirstName(string full_name) e string GetLastName(string full_name) per qualche motivo non hanno lo stesso parametro. Anche se se si prende proprio questo codice (non l'altro), i metodi privati sono chiamati attraverso quelli pubblici con gli stessi parametri e non c'è altro modo. Allora perché dovrei dare nomi diversi ai parametri?

Spero che la domanda sia chiara.

Motivazione: