尝试捕获__最终在C ++ Builder中使用

Cod*_*345 1 c++ c++builder try-catch-finally

我是否认为以下代码块是正确的:

try
    {
    Screen->Cursor = crHourGlass;
    try
        {
        throw Exception("error!");
        }
    catch(Exception& e)
        {
        Application->MessageBox(UnicodeString(e.Message).c_str(), L"Error", MB_OK);
        }
    }
__finally
    {
    Screen->Cursor = crDefault;
    }
Run Code Online (Sandbox Code Playgroud)

实际上是否与此相同,并且__finally在这里毫无用处,因为在两种情况下,无论如何都将执行Screen-> Cursor = crDefault

Screen->Cursor = crHourGlass;
try
    {
    throw Exception("error!");
    }
catch(Exception& e)
    {
    Application->MessageBox(UnicodeString(e.Message).c_str(), L"Error", MB_OK);
    }
Screen->Cursor = crDefault;
Run Code Online (Sandbox Code Playgroud)

Cod*_*ler 5

不,因为您仅捕获Exception类型的异常。如果发生其他异常,则在第二版代码中将不会执行Screen-> Cursor = crDefault


Rem*_*eau 5

回答您的问题 - 不,它们不相同,因为crDefault如果发生意外情况,在第二个版本中跳过分配的可能性很小。第__finally一个版本中的通常会处理这个问题。

话虽如此,另一种方法是使用 RAII 容器而不是__finally,例如:

class TUpdateScreenCursor
{
private:
    TCursor m_Original;

public:
    TUpdateScreenCursor(TCursor NewCursor)
    {
        m_Original = Screen->Cursor;
        Screen->Cursor = NewCursor;
    }

    ~TUpdateScreenCursor()
    {
        Screen->Cursor = m_Original;
    }
};
Run Code Online (Sandbox Code Playgroud)

{
TUpdateScreenCursor sc(crHourGlass);
try
    {
    throw Exception("error!");
    }
catch (const Exception& e)
    {
    Application->MessageBox(e.Message.c_str(), _D("Error"), MB_OK);
    }
}
Run Code Online (Sandbox Code Playgroud)