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