Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.5k views
in Technique[技术] by (71.8m points)

C++ 异常变量生命周期问题

C++ 异常throw抛出一个匿名对象的地址, catch捕获类型为该匿名对象的指针, 运行起来的效果是没有执行到catch下的异常输出, 对象就已经被释放掉了, 当改为抛出匿名对象时, catch处引用接收就不会发生这样的问题。

当抛出匿名对象时也就是说匿名对象被构建了, catch处的引用指向了这块对象。

抛出匿名对象地址跟抛出匿名对象后引用接收应该是一个意思吧? 我在catch处用指针接收这个地址为什么会被提前释放掉?

代码:

class A
{
public:
    A() { cout << "默认构造" << endl; }
    ~A() { cout << "默认析构" << endl; }
    A(const A &a) { cout << "拷贝构造" << endl; }
};

void work()
{
    throw &A();
}
int main()
{
    try{
        work();
    }
    catch (A *a)
    {
        cout << "捕获到异常" << endl;
    }
}

执行输出:
默认构造
默认析构
捕获到异常

可以看到还没输出异常信息就已经被析构了。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

except.throw#3

Throwing an exception copy-initializes ([dcl.init], [class.copy]) a temporary object, called the exception object. An lvalue denoting the temporary is used to initialize the variable declared in the matching handler ([except.handle]). If the type of the exception object would be an incomplete type or a pointer to an incomplete type other than cv void the program is ill-formed.

throw 会拷贝构造一个临时对象。

原对象析构了,引用方式可以 catch 到这个临时对象。

但是指针方式,由于只是拷贝了一个指针,指针指向的对象已经析构了,所以就不成了。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.5k users

...