Oppure

Loading
07/07/10 12:41
Butterfly
è sempre opportuno inserire sia un costruttore predefinito che uno con parametri? perchè?
aaa
07/07/10 12:48
No ... chi te lo ha detto?
07/07/10 12:50
Butterfly
Nessuno,solo che in tutti gli esercizi che ho fatto erano presenti entrambi,e mi chiedevo se fosse solo una coincidenza. Quindi come dovrei regolarmi?
aaa
07/07/10 13:21
HeDo
Postato originariamente da Butterfly:

Nessuno,solo che in tutti gli esercizi che ho fatto erano presenti entrambi,e mi chiedevo se fosse solo una coincidenza. Quindi come dovrei regolarmi?


se la classe ha bisogno di inizializzare dei campi interni o delle strutture di dati interne basandosi su dati esterni, passi quei dati nel costruttore.
Se non ha bisogno di dati esterni ma deve solo creare/inizializzare degli oggetti interni si usa il costruttore senza parametri (che ovviamente sovrascrive quello di default).
aaa
07/07/10 13:25
TheKaneB
Ti faccio 3 esempi di classici utilizzi dei costruttori con parametri, in modo che ti possa fare un'idea:

- Costruttore per copia: passi come parametro un const reference ad un oggetto dello stesso tipo. Durante la costruzione verranno copiati tutti i membri e verranno eseguite tutte le operazioni necessarie per utilizzare il nuovo oggetto. Se l'oggetto di partenza contiene dei puntatori, con questo metodo è possibile allocare nuova memoria e copiare il contenuto dei rispettivi buffer, anzichè copiare i puntatori (cosa che renderebbe i due oggetti in qualche modo interdipendenti).
MyString::MyString(const MyString& copiami)
{
  m_uiSize = copiami.m_uiSize;
  m_pData = new char[m_uiSize];         // creo un nuovo buffer, invece di linkare a quello vecchio
  memcpy(m_pData, copiami.m_pData, m_uiSize); // creo una copia dei dati nel nuovo buffer
}


- Oggetto con ID univoco: se l'oggetto viene creato da un'apposita Factory, ci sarà probabilmente la necessità di assegnarli un ID univoco (anche un semplice unsigned int può andare bene). Questo ID non potrà più essere modificato, ma soltanto letto.
UIWidget::UIWidget(unsigned int id)
{
  m_ID = id;   // m_ID è privato
}

// creo il getter, ma non il setter
unsigned UIWidget::getID() const
{
  return m_ID;
}

// Per evitare duplicazioni di oggetti con ID uguali, dichiaro un costruttore per copia come privato, la cui implementazione è vuota.
class UIWidget
{
//...
private:
  UIWidget(const UIWidget& other) {}
//...
};




- Costruzione per conversione: Se voglio convertire un oggetto dal tipo A al tipo B, posso prevedere un costruttore che richiede come parametro un reference (o un puntatore) ad un oggetto di tipo A. Un esempio arcistrausato è questo:
MyString::MyString(const char *szCopiami)
{
  m_uiSize = strlen(szCopiami) + 1;   // misuro la stringa
  m_pData = new char[m_uiSize];       // alloco lo spazio necessario
  strcpy(m_pData, szCopiami, m_uiSize);  // copio i dati
}


Ci possono essere tanti altri utilizzi, ma il succo del discorso è che devi sfruttare a tuo vantaggio quello che il linguaggio ti offre. Non scrivere codice a casaccio, senza prima riflettere sui possibili modi in cui questo codice verrà usato. :k:
aaa
07/07/10 13:49
Butterfly
ok! grazie per l'aiuto ;)
aaa
07/07/10 20:18
lorenzo
però ci sono alcune precisazioni da fare sui due costruttori.

-costruttore senza parametri: viene usato per creare array di oggetti quindi in teoria bisogna stare attenti a che tipi di dati ci sono salvati nella classe.

-costruttore copia: importante dato che entra in gioco nel passaggio parametri ad una funzione/metodo. Senza un costruttore copia scritto a mano il compilatore ne inserisce uno di default che copia i dati bit per bit, provocando quindi possibili collegamenti tra classi non voluti.

In definitiva secondo me è sempre meglio metterli, tanto non si sbaglia.
aaa