Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 函数返回std::wstring=NULL;_C++_Exception Handling_Error Handling - Fatal编程技术网

C++ 函数返回std::wstring=NULL;

C++ 函数返回std::wstring=NULL;,c++,exception-handling,error-handling,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, w

我正在尝试为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;    
}
扔一个硬币代替

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");    
}

NULL肯定是确定的。对于字符串,特别不允许向字符串构造函数传递NULL指针


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

作为异常的替代方法,您还可以通过在参数列表中引用返回字符串,并通过返回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();
}

WinApi的设计使其永远不会引发异常。要想知道某个函数返回失败的原因,在大多数情况下,您必须通过获取最后一个错误。据我所知,您的函数将是WinApi的一个补充,它将易于使用。所以我建议保留他们的设计。i、 e.如果失败,返回空字符串,如果函数返回,则检查最后一个错误是什么

另一种解决方案(不引发异常):使用库。

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

第二,如果确定,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();
}

根据您的应用程序,有几种合适的 解决。第一种是在发生异常时抛出异常 错误:如果执行此路线,则应定义WindowsError 异常(源自标准异常之一),其中 包括
GetLastError
中提供的所有信息, 以及可能的附加信息(用于 失败等),以易于解析的格式。二是 返回某种类型的
易出错的
;在这种情况下,您可能需要
扩展经典的
Fallible
习惯用法,使其能够包含 有关错误原因的其他信息。仍然 另一种可能是通过out参数返回值, 并使用返回码(同样,可能带有额外的 信息,并可能添加代码以确保
在被破坏之前已经测试过了。)

不要认为这是个好主意。通常winapi函数不会引发异常。最好是通过<代码> SETLASTRATROR()/< > Mihran >:设置为C++包装器,因此在C++习语中转换WiAPI的成语是正确的。如果它将
GetLastError
值封装在一个特定的异常类型中会更好。在这种情况下,他仍然必须返回一个值。它应该有什么价值?此外,每次调用此函数后调用
GetLastError
,比捕获异常要难看得多。我会计算代码以从故障代码生成错误消息,但在响应错误情况时抛出异常是完全正确的(假设不是操作系统接口本身在执行此操作;操作系统本身不抛出异常有一些很好的理由)。但如果所讨论的字符串实际上是空的,它将导致一个假错误。@Grigory-可能是的,这取决于接口的定义。但是,std::wstring(NULL)始终是一个错误,因为它违反了语言标准!请注意,这是
ValueWrapper
@ildjarn:谢谢。我不知道。请注意,
boost::optional
的一个名称在本例中有误导性——这里的常规名称是
易出错的
。(此外,还可以扩展一个
易出错的
,以便它包含有关错误的附加信息。)