命名空间
变体
操作

try

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
 
 
异常
try
抛出异常
处理异常
异常规范
    noexcept 规范 (C++11)
    动态规范 (直到 C++17*)
noexcept 运算符 (C++11)
 

try 块中抛出的 异常 可能被关联的处理块处理。

目录

[编辑] 语法

try 复合语句 处理块序列 (1)
try ctor-initializer (可选) 复合语句 处理块序列 (2)
2) 函数 try复合语句 必须是函数体的复合语句组件。
复合语句 - 复合语句
处理块序列 - 处理块 的非空序列
ctor-initializer - 成员初始化列表 (仅用于构造函数)

[编辑] 普通 try

普通 try 块是语句

如果从其 复合语句 抛出异常,则该异常将与在其 处理块序列 中的处理块 匹配 

void f()
{
    throw 1;     // NOT handled by the handler below
    try
    {
        throw 2; // handled by the associated handler
    }
    catch (...)
    {
        // handles the exception 2
    }
    throw 3;     // NOT handled by the handler above
}

[编辑] 函数 try

函数 try 块是一种特殊的函数体

如果从其 复合语句ctor-initializer (如果有) 抛出异常,则该异常将与在其 处理块序列 中的处理块 匹配 

int f(bool cond)
{
    if (cond)
        throw 1;
    return 0;
}
 
struct X
{
    int mem;
 
    X() try : mem(f(true)) {}
    catch (...)
    {
        // handles the exception 1
    }
 
    X(int) try
    {
        throw 2;
    }
    catch (...)
    {
        // handles the exception 2
    }
};

在具有静态存储期的对象的析构函数中或在与具有静态存储期的非块变量关联的对象的构造函数中抛出的异常,不会被 main 函数上的函数 try 块捕获。

在具有线程存储期的对象的析构函数中或在与具有线程存储期的非块变量关联的对象的构造函数中抛出的异常,不会被线程的初始函数上的函数 try 块捕获。

(自 C++11 起)

流出函数 try 块的 处理块复合语句 的末尾等效于流出该函数 compound-statementtry 块的末尾,除非该函数是构造函数或析构函数 (见下文)。

[编辑] 构造函数与析构函数 try

对于类 C,如果其构造函数或析构函数定义的函数体是函数 try 块,并且在 C 的子对象的初始化或销毁期间抛出异常,则该异常也将与函数 try 块的 处理块序列 中的处理块 匹配

int f(bool cond = true)
{
    if (cond)
        throw 1;
    return 0;
}
 
struct X
{
    int mem = f();
 
    ~X()
    {
        throw 2;
    }
};
 
struct Y
{
    X mem;
 
    Y() try {}
    catch (...)
    {
        // handles the exception 1
    }
 
    ~Y() try {}
    catch (...)
    {
        // handles the exception 2
    }
};

在构造函数或析构函数的函数 try 块的处理块中引用对象的任何非静态成员或基类会导致未定义行为。

如果 return 语句 出现在构造函数的函数 try 块的处理块中,则程序是非良构的。

如果控制到达构造函数或析构函数的函数 try 块的处理块的末尾,则会重新抛出当前处理的异常

[编辑] 控制流

try 块的 复合语句控制流受限语句

void f()
{
    goto label;     // error
    try
    {
        goto label; // OK
        label: ;
    }
    catch (...)
    {
        goto label; // error
    }
}

跳转语句 (goto, break, return, continue) 可用于将控制权转移出 try 块 (包括其处理块)。当这种情况发生时,在 try 块中声明的每个变量都将在直接包含其声明的上下文中销毁

try
{
    T1 t1;
    try
    {
        T2 t2;
        goto label; // destroy t2 first, then t1
    }
    catch(...)
    {
        // executed if an exception is thrown while destroying t2
    }
}
catch(...)
{
    // executed if an exception is thrown while destroying t1
}
label: ;

[编辑] 关键字

try

[编辑] 缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
CWG 98 C++98 switch 语句可以转移控制
try 块的 复合语句
被禁止
CWG 1167 C++98 在析构函数上的函数 try 块是否
会捕获来自基类或成员析构函数的异常,这是未指明的
此类异常
被捕获

[编辑] 参见