函数返回std :: wstring = NULL;

时间:2011-04-30 20:43:10

标签: c++ exception-handling error-handling

我试图为winapi函数GetWindowText创建包装器。 函数返回std :: wstring,但我不知道如何处理错误发生的地方。我返回NULL,但我知道这是错误的。

std::wstring GetWindowText(HWND handle)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    HRESULT hr = ::GetWindowText(handle,
                    wnd_text, size);
    if(SUCCEEDED(hr))
        return std::wstring(wnd_text);
    else
        return NULL;    
}

7 个答案:

答案 0 :(得分:7)

改为投掷exception

std::wstring GetWindowText(HWND handle)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    HRESULT hr = ::GetWindowText(handle,
                    wnd_text, size);
    if(SUCCEEDED(hr))
        return std::wstring(wnd_text);
    else
        throw std::runtime_error("insert error message here");    
}

答案 1 :(得分:5)

作为异常的替代,你也可以在参数列表中通过引用返回字符串,并通过返回true或false表示成功,即

bool GetWindowText(HWND handle, std::wstring& windowText)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    HRESULT hr = ::GetWindowText(handle,
                    wnd_text, size);
    if(SUCCEEDED(hr))
    {
        windowText = wnd_text;
        return true;
    }
    else
        return false;    
}

另一个避免引用参数的替代方法是返回一个包装值的类的实例,但也会让你知道是否存在一个值,例如

class ValueWrapper
{
public:
    ValueWrapper() : present( false ) {}
    ValueWrapper( const std::wstring& s ) : value( s ), present( true ) {}

    bool isPresent() const { return present; }
    const std::wstring& getValue() const { return value; }

private:
    std::wstring value;
    bool present;
};

请注意,您可以非常轻松地模拟此包装器。那么你的功能就是

ValueWrapper GetWindowText(HWND handle)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    HRESULT hr = ::GetWindowText(handle,
                    wnd_text, size);
    if(SUCCEEDED(hr))
        return ValueWrapper( wnd_text );
    else
        return ValueWrapper();
}

答案 2 :(得分:1)

另一种解决方案(不抛出异常):使用Boost.Optional库。

答案 3 :(得分:0)

对于字符串,

NULL肯定是确定,特别是不允许将空指针传递给字符串构造函数。

如果您不想抛出异常,可以返回空字符串return std::wstring();

答案 4 :(得分:0)

WinApi的设计使它永远不会抛出异常。并且为了获得某些函数的一些不成功返回的原因,在大多数情况下,您必须通过GetLastError()获得最后一个错误。据我所知,你的功能将是WinApi的一些附加功能,易于使用。所以我建议保持他们的设计。即如果失败,则返回空字符串,并检查函数返回时的最后一个错误。

答案 5 :(得分:0)

首先,GetWindowText()不会返回HRESULT,因此您的代码在这方面是错误的。

第二,如果OK,则GetWindowTextW在任何错误或字符数上返回0。 所以只返回一个空字符串:

std::wstring GetWindowText(HWND handle)
{
    const int size = 1024;
    TCHAR wnd_text[size] = {0};

    INT n = ::GetWindowTextW(handle,
                    wnd_text, size);
    if(n > 0)
        return std::wstring(wnd_text,n);
    else
        return std::wstring();
}

答案 6 :(得分:0)

根据您的应用程序,有几个适当的 解决方案。第一种是在发生异常的情况下抛出异常 错误:如果你走这条路,你应该定义一个WindowsError 异常(源自标准异常之一),其中 包括GetLastError提供的所有信息, 以及可能的附加信息(功能名称 失败等等,以易于解析的格式。另一个是 返回某种Fallible;在这种情况下,您可能想要 扩展经典的Fallible成语,以便它可以包含 有关错误原因的其他信息。仍然 另一种可能性是通过out参数返回值, 并使用返回代码(再次,可能还有额外的 信息,并可能添加代码以确保它具有 在被毁坏之前经过测试。)