【问题标题】:RAII with boost boost::program_options and options_description带有 boost boost::program_options 和 options_description 的 RAII
【发布时间】:2014-10-19 09:45:10
【问题描述】:

按照网上From this answer 上的一个例子,我想出了这个:

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&lt;boost::program_options::value_semantic const &gt;(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&lt;boost::program_options::typed_value&lt;int,char&gt;,std::default_delete&lt;boost::program_options::typed_value&lt;int,char&gt; &gt; &gt;::~unique_ptr&lt;boost::program_options::typed_value&lt;int,char&gt;,std::default_delete&lt;boost::program_options::typed_value&lt;int,char&gt; &gt; &gt;() Line 1449

  • std::default_delete&lt;boost::program_options::typed_value&lt;int,char&gt; &gt;::operator()(boost::program_options::typed_value&lt;int,char&gt; * _Ptr) Line 1200

再次在delete 指令中。


所以看起来options_description 破坏了(位于的对象)通过add_options 接收的指针,问题是由同一对象上的 2 次破坏引起的。

这不应该记录在案吗?这不违反 RAII 吗?调用者创建对象,但它被另一个对象销毁,该对象在某个时候接收到指向它的指针。 `


我使用 boost_1_56_0Visual Sudio 2013 运行 debug x64 配置。

【问题讨论】:

  • 在文档中有点像mentioned,但目前的设计真的很丑。推荐的方法是使用 po::value 无论如何通过“new”创建 po::typed_value
  • @frymode 它提到了使用原始指针背后的动机,它没有提到它拥有指针的所有权。唯一提到所有权的是:Note: it would be nice to make the second parameter auto_ptr, to explicitly pass ownership. 这个声明并没有明确说明它实际上拥有所有权。
  • boost 库的一个问题是,通过保持与 C++03 的兼容性,它们的设计对于后续版本可能不是最优的。在 C++11 中,unique_ptr 将是表达所有权传递的首选惯用语;在 C++03 中,有些人使用原始指针,因为 auto_ptr 被鄙视(由于其笨拙的复制语义)。

标签: c++ boost unique-ptr raii boost-program-options


【解决方案1】:

您使用它的方式确实不完全是 RAII。 unique_ptr 是一个不错的尝试。你要做的就是打电话给release()而不是get()

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

【讨论】:

    猜你喜欢
    • 2020-09-08
    • 2012-08-24
    • 2011-01-14
    • 1970-01-01
    • 2011-10-30
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    相关资源
    最近更新 更多