谁负责删除方面?

时间:2013-07-22 03:50:41

标签: c++ c++11 locale

我有一个使用Boost.DateTime库生成当前GMT / UTC日期和时间字符串(live example)的函数。

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's example

//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 ed 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"));

但是,正如here中所见,我遇到了段错误。我还尝试delete new ed指针,我仍然得到相同的错误(抱歉,无法在Coliru中重现错误)。

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

所以这是我的问题的核心:

  • 我需要delete time_facet ,还是负责std::locale delete的{​​{1}}对象?

请注意,boost::posix_time::time_facet源自boost::date_time::date_facet,而std::locale::facet来自std::locale::facet。此问题可能会推广到time_facet,但我的问题仅针对std::locale

以下是{{1}}的构造函数的一些文档:

3 个答案:

答案 0 :(得分:26)

  

我是否需要删除time_facet或者是std :: locale对象   负责删除它吗?

只要time_facet time_facet派生自std::locale::facet,就不需要删除std::locale::facetuse_facet<>是一个基类,所有方面都应该从该实现派生一种引用计数形式。标准说明了这一点:

§22.3.1.6

  

通过调用从区域设置对象获取构面引用   std::locale,该引用仍然可用,结果来自   它的成员函数可以被缓存和重用,只要一些   locale对象指的是那个方面。

一旦没有使用facet的所有引用,refs == 0的析构函数将管理和删除对facet的引用,如果它的引用计数为0。

这在C ++ 11标准的§22.3.1.1.2中都有说明。它声明:

  

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

     

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

答案 1 :(得分:5)

没有回答你的问题,因为其他人已经这样做了。但是,每次都不需要构建语言环境。

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();
}

答案 2 :(得分:2)

语言环境负责删除方面。