在 C++ 中抛出 e 引用时本地 var 销毁

local var destroy when throw e for refer in c++?

本文关键字:var 销毁 引用 C++      更新时间:2023-10-16

代码示例一:

try {
    exception e;
    throw e;
} catch(exception& refer)

代码示例二:

exception& method()
{
    exception e;
    return e;
}

有些书提到代码示例一没问题,代码二是错误的,因为其中e是一个局部变量,函数结束时会破坏,但我的问题是为什么示例代码一可以吗?e不也是局部变量吗?

是的,在示例 1 中,e 是 try 块的本地,并在退出该范围时销毁。 但是当你抛出时,编译器会创建一个副本(或移动),谁的生存期延长到 catch 块的末尾,而引用refer引用的正是这个副本。

为了弄清楚编译器在这种情况下做了什么,我总是喜欢拿出我的Noisy类。

#include <iostream>
class Noisy
{
public:
    Noisy()
        { std::cout << "Noisy default constructn"; }
    Noisy(Noisy const&)
        { std::cout << "Noisy copyn"; }
    Noisy(Noisy&&)
        { std::cout << "Noisy moven"; }
    ~Noisy()
        { std::cout << "Noisy destroyn"; }
    Noisy& operator=(Noisy const&)
        { std::cout << "Noisy copy assignn"; return *this; }
    Noisy& operator=(Noisy&&)
        { std::cout << "Noisy move assignn"; return *this; }
    void swap(Noisy&)
        { std::cout << "Noisy swapn"; }
};
int main(int argc, char* argv[])
{
    try
    {
        std::cout << "in try blockn";
        Noisy n;
        std::cout << "about to throw nn";
        throw n;
        std::cout << "end of try blockn";
    }
    catch (Noisy & n)
    {
        std::cout << "in catch blockn";
    }
    std::cout << "after catchn";
}