1

请原谅我,我是一个英语很差的中国人。我希望我正确地表达了这些事情。

我认为没有必要通过检查 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更安全,不是吗?

4

0 回答 0