请原谅我,我是一个英语很差的中国人。我希望我正确地表达了这些事情。
我认为没有必要通过检查 C++ 世界中某种类型的引用计数来释放 obj。我相信大多数 c++ 程序员会认为 RAII 是一种更好的方法。那么,为什么std::facet
像这样由 STL 实现呢?出于历史原因(在 C++11 之前)?
众所周知,std::numpunct 的构造函数接收一个参数(size_t ref)来控制自身的销毁。如果 "ref" 为 0,std::numpunct 的这个 obj 将被自动释放。我已经学会了如何使用它正确编码并实现了一个格式化程序,如下所示。
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更安全,不是吗?