Прошу прощения, я китаец с очень плохим знанием английского языка. Я надеюсь, что я правильно выражаю вещи.
Я не думаю, что необходимо освобождать объект, проверяя подсчет ссылок какого-либо типа в мире C ++.
Я полагаю, что большинство программистов на c ++ считают RAII лучшим методом.
Итак, почему std::facet
был реализован STL, как эти?
По историческим причинам (до C ++ 11)?
Как мы знаем, конструктор std :: numpunct получает параметр (size_t ref), который управляет уничтожением самого себя.
Если "ref" равен 0, этот объект std :: numpunct будет освобожден автоматически.
Я научился правильно кодировать его и реализовал Formater следующим образом.
struct GrouingDigits_T : std::numpunct<char> {
GrouingDigits_T( char p_cDigits, size_t p_uiRef = 1 ) :
std::numpunct<char>( p_uiRef ),
m_iDigits( p_cDigits ) {};
string do_grouping() const override {
return string( 1, m_iDigits );
};
char m_iDigits = 4;
/* yes, We Chinese people are prefer to read numbers grouped into
4 digits. Sorry for my ugly English.*/
};
template<typename T>
inline std::string formatNumber( const T & p_Value,
size_t p_uiWidth = 0,
size_t p_uiPrec = 2,
size_t p_uiGroup = 4,
char p_cFill = ' ' ) {
ostringstream oss;
// solution1 likes the sample in cppreference:
locale locGrpDigits(
oss.getloc(),
new GrouingDigits_T( static_cast<char>( p_uiGroup ), 0 ) );
// solution2:
GrouingDigits_T gd( static_cast<char>( p_uiGroup ), 1 );
locale locGrpDigits( oss.getloc(), &gd );
oss.imbue( locGrpDigits );
oss << std::fixed
<< std::setw( p_uiWidth )
<< std::setprecision( p_uiPrec )
<< std::setfill( p_cFill )
<< p_Value;
std::string strResult( oss.str() );
if ( p_uiWidth > 0 && strResult.length() > p_uiWidth )
return std::string( p_uiWidth, '*' );//too wide
else
return strResult;
};
Решение1 более вероятно приводит к утечке памяти или двойному освобождению, в то время как решение2 более безопасно, не так ли?