30

我有一个使用 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,所以我以某种方式假设我必须deletedate_facet. 我曾经std::unique_ptr包装newedtime_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设置newed 指针,但仍然遇到相同的错误(抱歉,无法在 Coliru 中重现错误)。

指针在time_facet构造对象时作为参数传递std::locale,所以我很困惑谁是负责deleteing 方面的人。

所以这是我问题的核心:

  • 我是否需要deletetime_facetstd::locale对象负责delete它?

请注意,boost::posix_time::time_facet源自boost::date_time::date_facetwhich 又源自std::locale::facet. 尽管我的问题std::locale::facet是特定于time_facet.

std::locale以下是关于的构造函数的一些文档:

4

3 回答 3

32

我需要删除 time_facet 还是 std::locale 对象负责删除它?

您不需要删除time_facet只要time_facet派生自std::locale::facet,它应该删除。这std::locale::facet是一个基类,所有方面都应该从它派生,实现一种引用计数形式。标准是这样说的:

§ 22.3.1.6

一旦通过调用从 locale 对象获得 facet 引用 use_facet<>,该引用仍然可用,并且它的成员函数的结果可以被缓存和重用,只要某个 locale 对象引用该 facet。

一旦没有使用 facet 的所有引用,std::locale如果其 ref 计数为 0,则析构函数将管理和删除对 facet 的引用。

这全部在 C++11 标准的 §22.3.1.1.2 中指定。它在哪里声明:

构造函数的 refs 参数用于生命周期管理。

— 对于refs == 0,当包含 facet 的最后一个 locale 对象被销毁时,实现执行delete static_cast<locale::facet*>(f)(其中 f 是指向 facet 的指针);因为 refs == 1,实现永远不会破坏刻面。

于 2013-07-22T04:01:01.983 回答
6

没有像其他人那样回答您的问题。但是,真的不需要每次都构建语言环境。

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();
}
于 2013-07-22T11:18:06.513 回答
2

语言环境负责删除构面。

于 2013-07-22T03:58:57.713 回答