Newsgroup: it.comp.lang.c++
Titolo: Parametri di default

Mmm il compilatore mi dą errore sul parametro di default...
...ma non ho capito come ovviare alla cosa:
class Message {
  string str;
public:
  Message(string str = "hello ");
  void print();
  void print(string add);
};
Message::Message(string str = "hello ") {
// codice :)
}
questo č l'errore che mi dą il compilatore di VC++6.0:
Message.cpp(24) : error C2572: 'Message::Message' :
redefinition of default parameter : parameter 1
        Message.cpp(19) : see declaration of
'Message::Message'
--
Lawrence Oluyede
rhy...@myself.com

 wrote in message
news:hfv0cus0uhnlav06p...@4ax.com...


Ora mi sono accorto del reale problema:
-------
class Message {
  string str;
public:
  Message(string str = "hello ");
  void print();
 /* ...... */
};
qui sopra vi è la classe il cui costruttore ha un parametro
string con valore di default
---------
---------
Message::Message(string str) {
/* ... */
}
questa è la definizione del costruttore
--------
int main() {
  Message msg("everybody");
  Message msg2();
  msg.print();
 // il problema sta proprio qua...il compilatore
 // dice che a sinistra di .print deve esserci una struct
 // una classe o una union....
  msg2.print();
}
--
Lawrence Oluyede
rhy...@myself.com


Message msg2() dichiara una funzione che ritorna un Message, non un oggetto
di tipo Message.
La dichiarazione corretta  e'
Message msg2;
Ora puoi tranquillamente chiamare msg2.print();
Ciao
Alex

Ora puoi tranquillamente chiamare msg2.print();
cavoli che svista... :(
--
Lawrence Oluyede
rhy...@myself.com

cavoli che svista... :(
E' la forma piu' comune della trappola "se puo' essere
intesa come dichiarazione allora e' una dichiarazione".
Introdurre questa regola non ha sicuramente reso la
vita piu' facile ai programmatori C++ e tantomento
agli scrittori di compilatori...
Andrea

 redefinition of default parameter : parameter 1
in effetti a prima vista si resta sconcertati, ma se ci pensi il 
compilatore ha ragione.
Lo standard non offre alcuna garanzia che due string literal uguali 
abbiano lo stesso indirizzo: puo` benissimo capitare qualcosa del genere:
char* s = "hello";
char* t = "hello";
s == t; // puo` essere false
a questo punto e` chiaro cosa succede: immagina che il compilatore metta 
il primo "hello" all'indirizzo 1000 e il secondo "hello" all'indirizzo 
2000: il tuo codice apparirebbe come se fosse:
Message(string s = (const char*)1000 ); // dichiarazione
Message(string s = (const char*)2000 ); // definizione
{
...
}
quindi il compilatore si lamenta perche` i due parametri di default non 
corrispondono.
Per risolvere ti basta non indicare nuovamente il parametro di default 
nella definizione.
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.73, higher than 99% of all previous test takers.
C Language: 3.79, higher than 92% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 [...mega cut...]
grazie mille per la spiegazione esauriente
--
Lawrence Oluyede
rhy...@myself.com


Beh, nel caso specifico l'istruzione puo' essere interpretata *solo*
come una dichiarazione.
Questa regola poi e' stata resa inevitabile dalla sintassi di
inizializzazione diretta introdotta dal C++.
Ciao,
Nicola

Nicola

 errore pero' no.
Piu' che di errore parlerei di compromesso, per quanto fastidioso.
Ciao,
Nicola

Piu' che di errore parlerei di compromesso, per quanto fastidioso.
Io non intendevo dire che quella scelta e' un "errore"
formale (e' oltretutto difficile dire che una definizione
di una regola e' "errata"). Io semplicemente intendevo
dire che da un punto di vista "pratico" si tratta di
qualcosa di molto molto fastidioso. Sostanzialmente un
"errore" come puo' essere un "errore" una cattiva
implementazione che comunque funziona.
Dire che la cosa formalmente sta in piedi non aggiunge
nulla alla questione che la maggior parte dei programmatori
C++ hanno qualche volta commesso quell'errore. Sicuramente
questo e' un caso in cui il principio della "minima
sorpresa" e' totalmente disatteso.
Io non ho mai indagato a fondo sul motivo per cui questa
bizzarra regola di ambiguita' era inevitabile (o per
meglio dire sul motivo per cui era indispensabile
introdurre l'ambiguita'). Forse non esistevano soluzioni
migliori e quindi quello che abbiamo, per quanto
disdicevole, e' il meglio che si potesse sperare.
In altri casi pero' le scelte fatte per il C++
non erano secondo me per nulla forzate e sono convinto
che se le si osserva senza pregiudizi non appaiono
essere certamente le migliori.
Andrea

 disdicevole, e' il meglio che si potesse sperare.
In effetti, a parte la distinzione concettuale tra inizializzazione e
assegnamento che mi pare sensata, non so se sia poi cosi' utile dal
punto di vista pratico avere una sintassi specifica (ambiguita' a parte)
per
A a1;
A a2(a1);
Piuttosto che usare sempre e solo:
A a3 = a1;
Ciao,
Nicola