Newsgroup: it.comp.lang.c++
Titolo: Costruttore OK sì o no???

Ciao a tutti,
premetto che (a parte 4 ore al liceo in Pascal) ho sempre programmato in
Java (il linguaggio più comodo che esista! se non fosse per la
pesantezza...) e quindi sono un novellino di C++ (un linguaggio, il più
diffuso e il migliore a detta di molti, che voglio imparare perchè mi
sembrano molto interessanti alcune funzionalità che offre), per cui non vi
stupite se le domande che faccio sono proprio stupide.
Stavo cercando di prendere confidenza con il linguaggio (queste sono le
prime righe che scrivo) e con il compilatore (gcc-Mingw) ma mi sono
imbattuto in questo ostacolo che mi sta facendo impazzire (forse è una
cazzata ma io ci sto sbattendo la testa da parecchio e ho esaurito le
risorse!). Stavo scrivendo una classe stupida, giusto per iniziare, e ho
creato un costruttore che accetta 4 parametri char * (in Java è molto più
semplice operare con le stringhe! :-( ). Nel main ho creato un oggetto della
classe con quel costruttore ed è andato tutto bene. Adesso avevo bisogno di
creare un array di oggetti User ma quando richiamo il costruttore per gli
elementi del vettore mi arriva dal compilatore questo errore:
..sc_user.cpp: 48: no match for call to `(User) (const char[5], const
char[8], const char[7], const char[6])'
..sc_user.cpp: 49: no match for call to `(User) (const char[5], const
char[8], const char[7], const char[6])'
..sc_user.cpp: 50: no match for call to `(User) (const char[5], const
char[8], const char[7], const char[6])'
[ecc... ecc...]
Il bello è che l'oggetto anotherUser, qualche riga dopo, lo inizializza
benissimo con quel costruttore, con gli stessi parametri, senza segnalarmi
nessun errore! Non so proprio dove sbattere la testa, mi sembra tutto
corretto quello che ho scritto!
Vi allego anche il sorgente completo, tanto sono solo poche righe.
Aiutatemi...
Grazie a tutti in anticipo,
Gio.Fresa
--- --- ---   --- --- ---
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
class User {
      private:
              unsigned int UserID;
              char Name[100];
              char Surname[100];
              char Password[100];
              static unsigned int UsersCounter;
      public:
             char Nick[100];
             User() {
             }
             User(char * nm, char * snm, char * pw, char * nk) {
                       UserID = ++UsersCounter;
                       Name[0] = '\0';
                       Surname[0] = '\0';
                       Password[0] = '\0';
                       Nick[0] = '\0';
                       strcat(Name, nm);
                       strcat(Surname, snm);
                       strcat(Password, pw);
                       strcat(Nick, nk);
             }
             char * getUserName() {
                  return Name;
             }
             char * getUserSurname() {
                  return Surname;
             }
             char * getUserPassword() {
                  return Password;
             }
             char * getUserNick() {
                  return Nick;
             }
             int getUserID() {
                 return UserID;
             }
};
unsigned int User::UsersCounter = 0;
int main() {
    User loggedIn[10];
    loggedIn[0]("Nome","Cognome","Chiave","Alias"); // <- ERRORE
    ecc...
    loggedIn[9]("Nome","Cognome","Chiave","Alias"); // <- ERRORE
    User anotherUser("Nome","Cognome","Chiave","Alias");
    cout << anotherUser.getUserName() << endl;
    cout << anotherUser.getUserSurname() << endl;
    cout << anotherUser.getUserPassword() << endl;
    cout << anotherUser.getUserNick() << endl;
    cout << anotherUser.getUserID() << endl;
    cout << anotherUser.Nick << endl;
    system("PAUSE");
    return 0;
}
--- --- ---   --- --- ---

     User anotherUser("Nome","Cognome","Chiave","Alias");
[cut]
E' naturale che in quel punto ci sia l'errore di compilazione.
Il costruttore è fatto per essere chiamato nel momento stesso della
dichiarazione dell'oggetto.
una sua chiamata successiva non è corretta dal punto di vista del
linguaggio.
User loggedIn[10]; <---- Questa chiamata è esatta perché chiama il
sostruttore user();
loggedIn[0]("Nome","Cognome","Chiave","Alias"); // <- ERRORE perchè
l'oggetto è già creato e il costruttore non può + essere richiamato una
seconda volta!
Spero di essere stato chiaro.
Ciao ciao.

    loggedIn[0]("Nome","Cognome","Chiave","Alias"); // <- ERRORE
loggedIn[0] e' gia' stato costruito; non puoi chiamare un'altra
volta il costruttore per quella istanza. Al limite potevi
dichiarare un metodo "Setup" che assegnasse tutti i campi ma e'
una tecnica che non e' sempre consigliabile (anzi).
Nota anche che tu hai scritto come costruttore di default
             User() {}
e questo significa che nei vari campi ci trovi "spazzatura";
non e' il sistema migliore e sicuramente non e' quello in linea
con la filosofia C++ (come anche usare un array di classi e
usare array di char per le stringhe).
Il mio consiglio spassionato e' di partire da un buon testo
sul C++... per chi sa gia' programmare a oggetti credo che
anche il testo di riferimento ("The C++ Programming Language"
3rd edition) possa essere una scelta ragionevole.
Benvenuto all'inferno ;)
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 }
Ti hanno già detto che l'errore dipende dal fatto che ti manca il
costruttore di default.
Per evitare che tu torni al Java al momento di affrontare i puntatori :)
ti consiglio di dare un'occhiata ai contenitori della libreria standard,
in particolare vector o deque nel tuo caso.
per esempio:
std::vector<User> loggedIn;
loggedIn.push_back(User("Nome","Cognome","Chiave","Alias"));
ecc...
loggedIn.push_back(User("Nome","Cognome","Chiave","Alias"));
cout << loggedIn[0].getUserNick() << endl;
cout << loggedIn[0].getUserID() << endl;
....
cout << loggedIn[loggedIn.size() -1].getUserNick() << endl;
cout << loggedIn[loggedIn.size() -1].getUserID() << endl;
Ciao.
--
"I bambini che ancora non sanno, nel loro Eden, il prezzo altissimo che un Dio
ingeneroso stabilirà per ogni singola mela: il prezzo della fatica e del
dolore."