谁负责删除分面
Who is responsible for deleting the facet?
我有一个函数,它使用 Boost.DateTime 库来生成当前的 GMT/UTC 日期和时间字符串(实时示例(。
std::string get_curr_date() {
auto date = boost::date_time::second_clock<boost::posix_time::ptime>::universal_time();
boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%a, %d %b %Y %H:%M:%S GMT");
std::ostringstream os;
os.imbue(std::locale(os.getloc(), facet));
os << date;
return os.str();
}
这主要基于 Boost.DateTime 的示例:
//example to customize output to be "LongWeekday LongMonthname day, year"
// "%A %b %d, %Y"
date d(2005,Jun,25);
date_facet* facet(new date_facet("%A %B %d, %Y"));
std::cout.imbue(std::locale(std::cout.getloc(), facet));
std::cout << d << std::endl;
// "Saturday June 25, 2005"
我的代码运行良好,但现在我感到不安,因为这些特定的行包含new
:
boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%a, %d %b %Y %H:%M:%S GMT");
date_facet* facet(new date_facet("%A %B %d, %Y"));
如您所见,Boost.DateTime中没有delete
,因此我不知何故认为我必须delete
date_facet
。我用std::unique_ptr
来包装new
time_facet
对象。
std::unique_ptr<boost::posix_time::time_facet> facet(new boost::posix_time::time_facet("%a, %d %b %Y %H:%M:%S GMT"));
但是,正如您在此处看到的那样,我遇到了段错误错误。我也尝试手动delete
new
ed指针,但仍然收到相同的错误(抱歉,无法在 Koliru 中重现错误(。
time_facet
指针在构造std::locale
对象时作为参数传递,所以我很困惑谁是负责delete
分面的人。
所以这是我问题的核心:
- 我是否需要
delete
time_facet
,还是std::locale
对象负责delete
它?
请注意,boost::posix_time::time_facet
派生自boost::date_time::date_facet
,而又派生自std::locale::facet
。这个问题可以推广到std::locale::facet
,尽管我的问题特定于time_facet
。
以下是一些关于std::locale
构造函数的文档:
- MSDN
- cppreference.com
我是否需要删除time_facet还是 std::locale 对象 负责删除它?
您不需要删除time_facet
,只要time_facet
派生自 std::locale::facet
,它应该这样做。std::locale::facet
是一个基类,所有方面都应派生自该基类,以实现引用计数的形式。该标准是这样说的:
§ 22.3.1.6
通过调用从区域设置对象获取分面引用后
use_facet<>
,该引用仍然可用,并且来自 它的成员函数可以被缓存和重用,只要一些 区域设置对象引用该方面。
一旦不使用分面的所有引用,std::locale
的析构函数将管理和删除对分面的引用(如果其引用计数为 0(。
这在 C++11 标准的 §22.3.1.1.2 中都有规定。其中指出:
构造函数的 refs 参数用于生存期管理。
— 对于
refs == 0
,实现执行delete static_cast<locale::facet*>(f)
(其中 f 是指向分面的指针( 当包含分面的最后一个区域设置对象被销毁时;为refs == 1
,实现永远不会破坏分面。
没有回答你的问题,因为其他人已经这样做了。但是,实际上不需要每次都构造区域设置。
std::string get_curr_date_time() {
namespace bpt = boost::posix_time;
namespace bdt = boost::date_time;
std::ostringstream os;
auto date = bdt::second_clock<bpt::ptime>::universal_time();
const static std::locale currlocale (os.getloc(), new bpt::time_facet("%Y%m%d%H%M%S"));
boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%a, %d %b %Y %H:%M:%S GMT");
os.imbue(currlocale);
os << date;
return os.str();
}
区域设置负责删除分面。
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 将指针设置为"nullptr"并不能防止双重删除?
- 为什么示例代码访问IUnknown中已删除的内存
- 如何通过 getter 函数删除矢量的元素?
- 从控制台中删除最后打印的元素
- C++中的线程安全删除
- 如何从存储在std::映射中的std::集中删除元素
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数