5

我在C++中做一个简单的线程服务器应用程序,事情是,我用libconfig ++来解析我的配置文件。那么,libconfig不支持多线程,因此我使用两个包装类来完成“支持”。重点是,他们中的一个失败:奇怪的“候选人期待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) 

因为我”,这是怪异明显地通过了一个论点,而且它的一个char *

那么,一如既往,任何帮助将不胜感激。

朱利安。

回答

10

您正在尝试默认构建您的配置,然后稍后分配给它。但是你没有默认的构造函数。

一个参数传递给一个成员变量的构造正确的方法是:

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

你仍然可以捕获该异常,使用了所谓的功能尝试块。见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

这解决了这个问题。然而,我计划传递一个变量字符串,而不是一个静态字符串,有没有什么办法可以实际处理我的app_main成员中的argc和argv变量,并在此之后初始化配置,而不是在初始化列表中? – 2012-01-16 06:05:01

+1

@JulianBayardoSpadafora:不可以。您可以将构造函数的参数传递给成员构造函数,而不仅仅是编译时常量。你也可以在* ctor-initializer-list *中调用静态成员函数。最后,您可以控制构建成员的顺序。但是你可能需要在此之前进行参数处理,并通过'getConfigFilename()'或者这样的成员函数传入某种选项捆绑对象。或者简单地给'app_config'一个函数来读取文件,而不是从构造函数中读取文件。 – 2012-01-16 06:14:27

4

首先,不要动态分配互斥体,也是没有用处的。其次,这是因为你有一个数据成员不能被默认构建,并且你没有在ctor init列表中初始化它。另外,千万不要将字符串文字分配给char*变量(如果你真的想用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; 
}