65.9K
CodeProject 正在变化。 阅读更多。
Home

HRESULT 错误检查简化器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.19/5 (12投票s)

2005 年 9 月 18 日

CPOL
viewsIcon

96785

downloadIcon

555

基于异常的错误检查,可自动执行 FAILED() 比较。

引言

编写大量的 if 语句仅仅为了检查失败情况是很繁琐的。与此同时,处理代码中可能发生的每一个错误非常重要。本文描述的类只是让每次从其他函数返回失败时都抛出异常变得容易。这样你就可以只做代码中需要做的事情,并统一错误处理。

在 CP 同事们的帮助下,这里有一个更新版本,包含一些用于无抛出版本的 traits,以及一个新的方法来显示 HRESULT 错误的文本版本

template<bool ThrowException>
struct HResultChecker
{
    static void Check(HRESULT hr);
};

template<> struct HResultChecker<false>
{
    static void Check(HRESULT hr) 
    {
        hr;
    }
};

template<> struct HResultChecker<true>
{
    static void Check(HRESULT hr)
    { 
        if( FAILED(hr) ) 
            AtlThrow(hr);
    }
};


/**
* Use this class instead HRESULT in order to the assignement operator be 
* tested. In case of failure, the funcion AtlThrow() will be called.
*
* @sa AtlThrow(), CAtlException.
*/
template<bool ThrowException>
class HResultT
{
public:
    /// Test the HRESULT in the constructor.
    HResultT(HRESULT hr = S_OK)    { Assign(hr); }

    /// Test failure of the received hr. If FAILED(hr), the function 
    /// AtlThrow() will be called.
    HResultT &operator = (HRESULT hr)
    {
        Assign(hr);
        return *this;
    }

    /** 
    * Retrieves the error desription of the HRESULT member.
    * @return string message for the HRESULT.
    *
    * @author ddarko (comment from CodeProject)
    * @date 2005-09
    */
    LPCTSTR ErrorMessage()
    {
        // a lot of code
    }

    /// Extractor of the stored HRESULT.
    operator HRESULT () { return m_hr; }

private:
    void Assign(HRESULT hr) // throw( CAtlException )
    {
        HResultChecker<ThrowException>::Check(m_hr = hr);
    }

    HRESULT m_hr; // the stored HRESULT
    std::basic_string<TCHAR> m_desc; // error description
};

/// Throw exception version.
typedef HResultT<true> HResult;

// No-Throw exception version.
typedef HResultT<false> HResultSafe;

使用代码

使用非常简单。你可以在函数内部捕获异常,也可以将其传递给调用者

/**
Using HResult inside the funcion
*/
void function()
{
   HResult hr;

   try
   {
      hr = MakeSomething();
      hr = MakeSomethingElse();
      hr = MakeTheFinalSomething();
   }
   catch(CAtlException& e)
   {
      cout << "wow! Error " << e.m_hr << ": " << e.ErrorMessage() << "\n";
   }
}

/**
Using HResult bypassing the exception
*/
void Class::Method() throw ( CAtlException )
{
   HResult hr = MakeSomething();
   hr = MakeSomethingElse();
   hr = MakeTheFinalSomething();
}

关注点

在使用上面的类之前,你可能想了解一下 CAtlExceptionAtlThrow()FormatMessage()。这些对于基于异常的错误处理来说是非常有趣的内容。

© . All rights reserved.