5

Sto realizzando una semplice applicazione server filettata in C++, che cosa è, io uso libconfig ++ per analizzare i miei file di configurazione. Beh, libconfig non supporta il multithreading, quindi sto usando due classi wrapper per realizzare il "supporto". Il punto è, uno di loro non riesce:Il "candidato si aspetta un argomento, 0 fornito" nel costruttore

class app_config { 
    friend class app_config_lock; 
public: 
    app_config(char *file) : 
     cfg(new libconfig::Config()), 
     mutex(new boost::mutex()) 
    { 
     cfg->readFile(file); 
    } 

private: 
    boost::shared_ptr<libconfig::Config> cfg; 
    boost::shared_ptr<boost::mutex> mutex; 
}; 

Fails orribilmente quando viene chiamato dal mio file main.cpp:

app_main::app_main(int c, char **v) : argc(c), argv(v) { 
    // here need code to parse arguments and pass configuration file!. 
    try { 
     config = app_config("mscs.cfg"); 
    } catch (libconfig::ParseException &e) { 
     cout << "Parse error at line " << e.getLine() << ": " << e.getError() << endl; 
     throw; 
    } catch (libconfig::FileIOException &e) { 
     cout << "Configuration file not found." << endl; 
     throw; 
    } 
} 

E dice:

main.cpp: In constructor ‘app_main::app_main(int, char**)’: 
main.cpp:38:54: error: no matching function for call to ‘app_config::app_config()’ 
main.cpp:38:54: note: candidates are: 
../include/app_config.h:15:5: note: app_config::app_config(char*) 
../include/app_config.h:15:5: note: candidate expects 1 argument, 0 provided 
../include/app_config.h:12:7: note: app_config::app_config(const app_config&) 
../include/app_config.h:12:7: note: candidate expects 1 argument, 0 provided 
main.cpp:41:39: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] (THIS CAN BE IGNORED, I WAS USING STD::STRING, YET CHANGED IT FOR TESTING PURPOSES) 

che è strano perché ho' m chiaramente passando un argomento, ed inoltre è un char *!

Bene, come sempre, ogni aiuto sarà apprezzato.

Julian.

risposta

10

Si sta provando a predefinire-costruire la configurazione e quindi assegnarla in seguito. Ma non hai un costruttore predefinito.

Il modo corretto per passare un argomento al costruttore di un membro variabile è:

app_main::app_main(int c, char **v) : argc(c), argv(v), config("mscs.cfg") 

È ancora possibile intercettare l'eccezione, utilizzando ciò che è noto come un funzione try-block. Vedere http://www.gotw.ca/gotw/066.htm

codice finale:

app_main::app_main(int c, char **v) 
try : argc(c), argv(v), config("mscs.cfg") 
{ 
    // more constructor logic here 
} catch (libconfig::ParseException &e) { 
    cout << "Parse error at line " << e.getLine() << ": " << e.getError() << endl; 
    throw; 
} catch (libconfig::FileIOException &e) { 
    cout << "Configuration file not found." << endl; 
    throw; 
} 
+0

Questo ha risolto il problema. Tuttavia, ho in programma di passare una stringa variabile, piuttosto che una stringa statica, c'è un modo per elaborare effettivamente le mie variabili argc e argv all'interno del mio membro app_main e inizializzare la configurazione successivamente, piuttosto che nella lista di inizializzazione? –

+1

@JulianBayardoSpadafora: No. È possibile passare gli argomenti del costruttore ai costruttori dei membri, non solo alle costanti di compilazione. E puoi anche chiamare le funzioni membro statiche all'interno della * lista-iniziatore-ctor *. Infine, hai il controllo sull'ordine in cui i membri sono costruiti. Ma probabilmente dovrai eseguire l'elaborazione degli argomenti prima di questo e passare una sorta di oggetto bundle di opzioni con un 'getConfigFilename()' o una funzione membro di questo tipo. O semplicemente dare a 'app_config' una funzione per leggere il file invece di farlo dal costruttore. –

4

Prima di tutto, non allocare dinamicamente mutex, non serve a niente. In secondo luogo, è perché si dispone di un membro dati che non può essere costruito in modo predefinito e non è stato inizializzato nella lista init di ctor. Inoltre, non assegnare mai stringhe letterali alle variabili char* (dovrebbe essere app_config(const char*) se si vuole dilettarsi con i puntatori di carattere).

tuo app_main::app_main dovrebbe apparire come questo, invece:

app_main::app_main(int c, char **v) try 
    : argc(c), argv(v), config("mscs.cfg") { 
} catch (libconfig::ParseException &e) { 
    cout << "Parse error at line " << e.getLine() << ": " << e.getError() << endl; 
    throw; 
} catch (libconfig::FileIOException &e) { 
    cout << "Configuration file not found." << endl; 
    throw; 
} 
Problemi correlati