命名空间
变体
操作

try

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

try 块中抛出的异常可能会由关联的处理程序处理。

目录

[编辑] 语法

try 复合语句 处理程序序列 (1)
try ctor-initializer (可选) 复合语句 处理程序序列 (2)
1) 一个普通 try
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 块的处理程序复合语句末尾,等同于流出该函数 try 块的复合-语句末尾,除非该函数是构造函数或析构函数(见下文)。

[编辑] 构造函数和析构函数 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
    }
}

跳转语句gotobreakreturncontinue)可用于将控制流转移出 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++ 标准。

缺陷报告 应用于 发布时的行为 正确的行为
CWG 98 C++98 一个 switch 语句可以转移控制
进入 try 块的复合语句
已禁止
CWG 1167 C++98 未指明析构函数上的函数 try 块是否
捕获来自基类或成员析构函数的异常
此类异常
被捕获

[编辑] 参阅