1

代码示例一:

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

代码示例二:

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

有些书提到代码示例一可以,代码二是错误的,因为e它是一个局部变量,并且会在函数结束时销毁,但我的问题是为什么示例代码一可以?不是e局部变量吗?

4

1 回答 1

3

是的,在示例一中,e它位于 try 块的本地,并在退出该范围时被销毁。但是当你抛出时,编译器会创建一个副本(或移动),其生命周期会延长到 catch 块的末尾,并且引用refer所指的是这个副本。

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

#include <iostream>

class Noisy
{
public:
    Noisy()
        { std::cout << "Noisy default construct\n"; }
    Noisy(Noisy const&)
        { std::cout << "Noisy copy\n"; }
    Noisy(Noisy&&)
        { std::cout << "Noisy move\n"; }
    ~Noisy()
        { std::cout << "Noisy destroy\n"; }
    Noisy& operator=(Noisy const&)
        { std::cout << "Noisy copy assign\n"; return *this; }
    Noisy& operator=(Noisy&&)
        { std::cout << "Noisy move assign\n"; return *this; }
    void swap(Noisy&)
        { std::cout << "Noisy swap\n"; }
};

int main(int argc, char* argv[])
{
    try
    {
        std::cout << "in try block\n";
        Noisy n;
        std::cout << "about to throw n\n";
        throw n;
        std::cout << "end of try block\n";
    }
    catch (Noisy & n)
    {
        std::cout << "in catch block\n";
    }
    std::cout << "after catch\n";
}
于 2013-10-16T00:55:38.157 回答