2013-07-22 11 views
23

Mam funkcję korzystającą z biblioteki Boost.DateTime do generowania bieżącego łańcucha daty i czasu GMT/UTC (live example).Kto jest odpowiedzialny za usunięcie aspektu?

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

ta opiera się głównie na 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" 

Mój kod pracował dobrze, ale teraz czuję się nieswojo z powodu tych konkretnych linii zawierających 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"));

Jak widać, nie ma delete w Boost.DateTime jest tak jakoś domniemywać, że jest to konieczne dla mnie deletedate_facet. Użyłem std::unique_ptr do zawijania obiektu 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")); 

Jednak ja dostaję błędy segfault, jak widać w here. Próbowałem również ręcznie delete ed wskaźnik delete i nadal otrzymuję te same błędy (przepraszam, nie można odtworzyć błąd w Coliru).

Wskaźnik time_facet jest przekazywany jako argument podczas konstruowania obiektu std::locale, więc jestem zdezorientowany, kto jest odpowiedzialny za aspekt.

Więc tutaj jest sedno mojego pytania:

  • Czy jestem zobowiązany do deletetime_facet lub jest przedmiotem std::locale odpowiedzialny za delete ing go?

Uwaga boost::posix_time::time_facet pochodzi od boost::date_time::date_facet który z kolei pochodzi od std::locale::facet. To pytanie może zostać uogólnione na std::locale::facet, chociaż mój problem jest specyficzny dla time_facet.

Oto kilka Docs na konstruktorów std::locale „s:

Odpowiedz

24

Czy muszę usunąć plik time_facet lub czy obiekt std :: locale jest odpowiedzialny za jego usunięcie?

Nie jesteś zobowiązany do usunięcia time_facet tak długo, jak time_facet wywodzi std::locale::facet, co powinno. Klasa std::locale::facet jest klasą podstawową, z której wszystkie aspekty powinny pochodzić, aby zaimplementować formę liczenia odwołań. Norma mówi tak:

§ 22.3.1.6

Po odniesienie aspekt jest otrzymywany z obiektu locale wywołując use_facet<>, że odniesienia pozostaje do wykorzystania, a wyniki z funkcji członkowskich może on być buforowane i ponownie używane, o ile jakiś lokalny obiekt odnosi się do tego aspektu.

Gdy wszystkie odniesienia do aspektu nie są używane, destruktor z std::locale będzie zarządzać i usuwać odniesień do aspektu, jeżeli jego ref liczba 0.

To wszystko jest określone w §22.3.1.1. 2 w standardzie C++ 11. Gdzie stwierdza:

Argument refs do konstruktora służy do zarządzania całym życiem.

- Dla refs == 0 implementacja wykonuje delete static_cast<locale::facet*>(f) (gdzie f jest wskaźnikiem do aspektu) , gdy ostatni obiekt lokalizacji zawierający aspekt zostanie zniszczony; dla refs == 1 implementacja nigdy nie niszczy aspektu.

2

Locale jest odpowiedzialny za usunięcie aspekt.

+0

Oznacza to, że ustawienia regionalne nie mogą być zadeklarowane jako "const static"? – agodinhost

5

Brak odpowiedzi na twoje pytanie, tak jak inni już to zrobili. Ale tak naprawdę nie jest konieczne tworzenie lokalizacji za każdym razem.

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(); 
} 
Powiązane problemy