2014-10-19 79 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");