5

Я делаю простую прикладную программу с потоковыми серверами в C++, дело в том, что я использую libconfig ++ для анализа файлов конфигурации. Ну, libconfig не поддерживает многопоточность, поэтому я использую два класса-оболочки для выполнения «поддержки». Пойнт, один из них не удается:Weird «кандидат ожидает 1 аргумент, 0 предоставлен» в конструкторе

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

Не удается ужасно при вызове из моего 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; 
    } 
} 

И он говорит:

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) 

Что странно, потому что я m ясно передавая аргумент, и, кроме того, его a char *!.

Ну, как всегда, любая помощь будет оценена по достоинству.

Julian.

ответ

10

Вы пытаетесь создать свою конфигурацию по умолчанию, а затем назначьте ее позже. Но у вас нет конструктора по умолчанию.

Правильный способ передать аргумент конструктору переменной-члена является:

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

Вы все еще можете перехватить исключение, используя то, что известно как функция Try-блок. См http://www.gotw.ca/gotw/066.htm

Окончательного код:

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

Это решило проблему. Тем не менее, я планирую передать переменную строку, а не статическую строку, есть ли способ, которым я могу фактически обрабатывать переменные argc и argv в моем члене app_main и инициализировать конфигурацию после этого, а не в списке инициализации? –

+1

@JulianBayardoSpadafora: Нет. Вы можете передать аргументы конструктора конструкторам-членам, а не только константам времени компиляции. И вы также можете вызвать статические функции-члены внутри * ctor-initializer-list *. Наконец, вы контролируете порядок, в котором создаются члены. Но вам, вероятно, нужно будет обработать аргументы до этого и передать какой-то объект пакета с параметром 'getConfigFilename()' или такую ​​функцию-член. Или просто дайте 'app_config' функцию для чтения файла вместо того, чтобы делать это из конструктора. –

4

Прежде всего, не выделяют мьютексы динамически, он не служит никакой цели. Во-вторых, это потому, что у вас есть член данных, который не может быть сконфигурирован по умолчанию, и вы не инициализировали его в списке инициализации ctor. Кроме того, никогда не присваивайте строковые литералы переменным char* (это должно быть app_config(const char*), если вы действительно хотите использовать указатели на символы).

Ваш app_main::app_main должен выглядеть следующим образом, вместо:

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