简体   繁体   English

为什么要捕获一个const int和一个int&work?

[英]Why does catching a const int& by an int& work?

In the following code, I throw an int, catch it as const int&, re-throw it and catch it again catch it as an int&. 在下面的代码中,我抛出一个int,将其捕获为const int&,重新抛出它并再次捕获它将其作为int&捕获。

#include <iostream>

int main()
{
    try
    {
        try
        {
            int x = 1;
            throw x;
        }
        catch(const int& e)
        {
            std::cout << "Inner catch" << std::endl;
            throw;
        }
    }
    catch(int & e1)
    {
        std::cout << "Outer catch" << std::endl;
    }

    return 0;
}

The above program compiles successfully and prints 上面的程序编译成功并打印

Inner catch
Outer catch

On the other hand the following program in which I am trying to initialize an int& by a const int& wouldn't even compile. 另一方面,下面的程序,我试图初始化一个int和一个const int,甚至不会编译。

#include <iostream>
int main()
{
    int x = 0;
    const int& y = x;
    int& z = y 
    return 0;
}

I get the following error as expected 我按预期得到以下错误

binding ‘const int’ to reference of type ‘int&’ discards qualifiers
     int& z = y

Why am I allowed to catch an const int& as an int& but not able to assign cons int& to int&? 为什么我被允许捕获一个const int&作为一个int&但是不能指定cons int&to int&?

except.handle/3 : 除了.handle / 3

A handler is a match for an exception object of type E if 处理程序是E类型的异常对象的匹配项
(3.1) – The handler is of type cv T or cv T& and E and T are the same type ( ignoring the top-level cv-qualifiers ), or [...] (3.1) - 处理程序的类型为cv Tcv T&ET是相同的类型( 忽略顶级cv限定符 ),或[...]

A throw is always by value. 抛出始终是值。 You can catch it with a const or with a reference if you want, but the object thrown is always a copy. 如果需要,可以使用const或引用来捕获它,但抛出的对象始终是副本。 So it's perfectly safe to catch it with a non- const and to modify it. 所以用非const来捕获它并修改它是完全安全的。 You can test this by printing the address of an int , then throw it, catch it by reference, and print the address of the reference. 您可以通过打印int的地址来测试它,然后抛出它,通过引用捕获它,并打印引用的地址。 You'll see it's a different address. 你会看到它是一个不同的地址。

You can even do this: 你甚至可以这样做:

try
{
    throw 3;
}
catch (int& q)
{
    q = 4;
}

The value of the thrown object with the value 3 is modified because q binds to a new int initialized with the thrown value. 修改了值为3的抛出对象的值,因为q绑定到使用抛出值初始化的新int You always throw a value. 你总是抛出一个值。

The exception is just throw; 例外是throw; , which re-throws the existing object. ,重新抛出现有的对象。 It has to be this way because otherwise, it would be impossible to sanely manage the lifetime of thrown objects. 它必须是这种方式,否则,不可能理智地管理抛出对象的生命周期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM