【发布时间】: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<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 1449std::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 次破坏引起的。
这不应该记录在案吗?这不违反 RAII 吗?调用者创建对象,但它被另一个对象销毁,该对象在某个时候接收到指向它的指针。 `
我使用 boost_1_56_0 和 Visual 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