2014-10-19 66 views
3

繼淨From this answer一個例子,我想出了這個:RAII與升壓Boost :: program_options和options_description

int server_port; 
auto value_port = new po::typed_value<int>(&server_port); //<-- Really?? 
value_port->value_name("port"); 

po::options_description opt_config("Configuation"); 
opt_config.add_options()("port,P", value_port, "listening port"); 

這顯然作品。但是明確地調用new來創建原始指針在C++中引發了警報鈴聲。


所以,我想的第一件事就是使用靜態分配對象。 (我沒有看到動態分配內存的需求在這裏):

auto value_port = po::typed_value<int>(&server_port); 
value_port.value_name("port"); 

po::options_description opt_config("Configuation"); 
opt_config.add_options()("port,P", &value_port, "listening port"); 

這在函數退出給出一個運行時錯誤(正在破壞變量時)。
調用棧與

  • boost::detail::shared_count::~shared_count() Line 447

開始並且誤差是在

  • boost::checked_delete<boost::program_options::value_semantic const >(const boost::program_options::value_semantic * x) Line 34

那裏有一個delete指令。


我試過的第二件事是用unique_ptr(從std):

auto value_port = make_unique<po::typed_value<int>>(&server_port); 
value_port->value_name("port"); 

po::options_description opt_config("Configuation"); 
opt_config.add_options()("port,P", value_port.get(), "listening port"); 

故事是相似的,2幀此時調用堆棧上:

  • std::unique_ptr<boost::program_options::typed_value<int,char>,std::default_delete<boost::program_options::typed_value<int,char> > >::~unique_ptr<boost::program_options::typed_value<int,char>,std::default_delete<boost::program_options::typed_value<int,char> > >() Line 1449

  • std::default_delete<boost::program_options::typed_value<int,char> >::operator()(boost::program_options::typed_value<int,char> * _Ptr) Line 1200

再次在 delete指令


所以好像options_description自毀(在對象)經由add_options接收到的指針和問題是由同一對象2個引起的破壞力。

這不應該記錄嗎? Doesn'ţ這不利於RAII?調用者創建該對象,但它被另一個對象所銷燬,該對象在某個時刻接收到一個指向它的指針。 '


我用boost_1_56_0Visual Sudio 2013運行debug x64配置。

+0

它還挺[提到](http://www.boost.org/doc/libs/1_56_0/doc/html/boost/program_options/option_description .html#boost.program_options.option_descriptionconstruct-copy-destruct),但目前的設計真的很難看。推薦的方法是使用po :: value ,無論如何通過「new」創建po :: typed_value 。 – dewaffled 2014-10-19 10:27:05

+1

@frymode它提到了使用原始指針的動機,它沒有提到它擁有指針的所有權。唯一提及所有權的是:'注意:將第二個參數auto_ptr明確地通過所有權是很好的做法。「這個聲明並沒有說明它實際上是否擁有所有權。 – bolov 2014-10-19 10:48:48

+0

boost庫的問題之一是,通過保持與C++ 03的兼容性,對於其他版本,它們的設計可能不夠理想。在C++ 11中,'unique_ptr'是表達這種所有權傳遞的最佳方式;在C++ 03中,有些人使用原始指針,因爲'auto_ptr'被鄙視(由於其複雜的語義)。 – 2014-10-19 13:45:28

回答

0

你使用它的方式確實不完全是RAII。 unique_ptr是一個不錯的嘗試。你所要做的就是調用release(),而不是get()

opt_config.add_options()("port,P", value_port.release(), "listening port");