2013-07-22 3 views
23

У меня есть функция, которая использует библиотеку 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"));

Как вы можете видеть, не существует ни в коем delete Boost.DateTime так я как-то предположил, что это важно для меня deletedate_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")); 

Однако я получаю Segfault ошибок, как вы можете видеть в here. Я также попробовал вручную delete с указателем new ed, и все еще получаю те же ошибки (извините, не могу воспроизвести ошибку в Coliru).

Указатель time_facet передается в качестве аргумента при создании объекта std::locale, поэтому я смущен тем, кто ответственен за фасетку delete.

Так вот суть моего вопроса:

  • Требуется ли deletetime_facet или является std::locale объект отвечает за delete ИНГ его?

Пожалуйста, обратите внимание, что boost::posix_time::time_facet происходит от boost::date_time::date_facet, который, в свою очередь, полученный из std::locale::facet. Этот вопрос может быть обобщен на std::locale::facet, хотя моя проблема связана с time_facet.

Вот некоторые документы на конструкторах std::locale «s:

ответ

24

Мне необходимо удалить time_facet или объект std :: locale , ответственный за его удаление?

Вы не обязаны удалить time_facet так долго, как time_facet происходит от std::locale::facet, что он должен. std::locale::facet - это базовый класс, из которого все грани должны извлекаться из этой реализации формы подсчета ссылок. Стандарт говорит, что это:

§ 22.3.1.6

После ссылки фаска получается из объекта локали путем вызова use_facet<>, что ссылка остается пригодным к использованию, а результаты функций членов его может быть кэшироваться и повторно использоваться, если какой-то объект ссылается на этот фасет.

После того, как все ссылки на грани не используются, деструктор std::locale будет управлять и удалять ссылки на грани, если его порядковый счетчик равен 0.

Все это указано в §22.3.1.1. 2 в стандарте C++ 11. Где указано:

Аргумент refs для конструктора используется для управления жизненным циклом.

- Для refs == 0, реализация выполняет delete static_cast<locale::facet*>(f) (где F представляет собой указатель на грани) , когда последний объект, содержащий локаль грань уничтожается; для refs == 1, реализация никогда не разрушает грань.

2

Языковой отвечает за удаление фасет.

+0

Это означает, что язык не может быть объявлен как «const static»? – agodinhost

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(); 
} 
Смежные вопросы