5

Tôi đang tạo một ứng dụng máy chủ luồng đơn giản trong C++, điều là, tôi sử dụng libconfig ++ để phân tích các tệp cấu hình của mình. Vâng, libconfig không hỗ trợ đa luồng, vì vậy tôi đang sử dụng hai lớp wrapper để thực hiện "hỗ trợ". Vấn đề là, một trong số họ thất bại:Lạ "ứng cử viên mong đợi 1 đối số, 0 được cung cấp" trong hàm tạo

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

Thất bại khủng khiếp khi gọi từ file main.cpp tôi:

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

Và nó nói:

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) 

Đó là lạ bởi vì tôi m rõ ràng đi qua một đối số, và hơn nữa một đối số của nó là char *!

Vâng, như mọi khi, mọi trợ giúp sẽ được đánh giá cao.

Julian.

Trả lời

10

Bạn đang cố định cấu hình mặc định của mình và sau đó gán cho cấu hình đó. Nhưng bạn không có một hàm tạo mặc định.

Cách đúng để vượt qua một cuộc tranh cãi với các nhà xây dựng của một biến thành viên là:

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

Bạn vẫn có thể bẫy ngoại lệ, bằng cách sử dụng những gì được biết đến như một chức năng thử khối. Xem http://www.gotw.ca/gotw/066.htm

mã cuối cùng:

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

này đã giải quyết được vấn đề. Tuy nhiên, tôi có kế hoạch đi qua một chuỗi biến, chứ không phải là một chuỗi tĩnh, có cách nào tôi thực sự có thể xử lý các biến argc và argv trong thành viên app_main của tôi và khởi tạo cấu hình sau đó, thay vì trong danh sách khởi tạo? –

+1

@JulianBayardoSpadafora: Không. Bạn có thể chuyển các đối số của hàm tạo tới các hàm tạo thành viên, không chỉ các hằng số biên dịch thời gian. Và bạn cũng có thể gọi các hàm thành viên tĩnh bên trong danh sách * ctor-initializer-list *. Cuối cùng, bạn có quyền kiểm soát thứ tự các thành viên được xây dựng. Nhưng có thể bạn sẽ cần phải thực hiện xử lý đối số trước đó, và truyền vào một số đối tượng bó tùy chọn với một hàm 'getConfigFilename()' hoặc hàm thành viên như vậy. Hoặc chỉ cần cung cấp cho 'app_config' một hàm để đọc tệp thay vì thực hiện nó từ hàm tạo. –

4

Trước hết, không phân bổ mutexes động, nó phục vụ không có mục đích. Thứ hai, đó là vì bạn có một thành viên dữ liệu không thể được xây dựng mặc định, và bạn đã không khởi tạo nó trong danh sách init ctor. Ngoài ra, đừng bao giờ gán các chuỗi ký tự cho các biến số char* (nó phải là app_config(const char*) nếu bạn thực sự muốn đánh dấu bằng các con trỏ char).

bạn app_main::app_main nên trông giống như thay vì điều này:

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