为什么捕获异常指针时异常不一样?

Why exception not the same when catching exception pointer?

我是 C++ 异常处理的新手。我试图抛出一个异常指针并捕获了它,但似乎后来捕获的异常与我抛出的异常不同。 这是我的代码:

try {
    bad_exception e2 = bad_exception();
    cout << e2.what() << endl;
    cout << &e2 << endl;

    throw &e2;
}
catch (bad_exception* ex) {
    cout << ex << endl;
    cout << ex->what() << endl;
    cout << (*ex).what() << endl;
}

输出:
错误异常
00CFFCF8
00CFFCF8
未知异常
未知异常

我预计后者会显示同名的“错误异常”。你能解释一下吗?

更新:
似乎异常具有“自动删除”功能?我尝试抛出一个指向普通对象的指针(不是从异常继承的)。但是我仍然可以在 catch 块中访问该对象及其属性。

try {
    char str[5] = "eed8";
    A a = A();
    a.name1 = str;

    cout << a.show() << endl;
    cout << &a << endl;

    throw &a;
}
catch (A* exp) {
    cout << exp << endl;
    cout << exp->show() << endl;
    cout << exp->name1 << endl;
}

输出:
eed8
007BF9DC
007BF9DC
eed8
eed8

您应该(通常)按值抛出异常。

这里的问题是您正在抛出一个指向对象的指针。不幸的是,当指针被捕获时,它指向的对象已经被销毁,因此你有一个无效的指针。

try {
    bad_exception e2 = bad_exception();
    cout << e2.what() << endl;
    cout << &e2 << endl;

    throw &e2;
}  // At this point the object "e2" goes out of scope
   // Thus its destructor is called.
   // So the pointer you threw now points at an invlalid object
   // Thus accessign the object via this pointer is UB.

catch (bad_exception* ex) {
    cout << ex << endl;
    cout << ex->what() << endl;
    cout << (*ex).what() << endl;
}

改写成这样:

try {
    bad_exception e2 = bad_exception();
    cout << e2.what() << endl;
    cout << &e2 << endl;

    throw e2; // Throw a copy.
              // Throw an object that gets copied to a secure location
              // so that when you catch it is still valid.
}
catch (bad_exception const& ex) {  // catch and get a reference to the copy.
    cout << &ex << endl;
    cout << ex.what() << endl;
}

如果你绝对必须抛出一个指针,那么使用 new 来确保指针有一个动态的生命周期(但记住,你需要清理它)。


更新:

It seems the exception has the "auto delete" feature?

不是东西。

I tried throwing a pointer to normal object (not inherited from exception).

异常对象(或其任何派生的 classes)没有什么特别之处。它只是一个普通的对象。像所有对象(class)一样,对象的析构函数是 运行 当对象到达其生命周期结束时。如果 A 没有析构函数,那么对象使用的内存可能不会改变(但它不能被不是你的对象的其他对象使用)。

But I can still access the object and its properties in the catch block.

这就是“未定义行为”不好的一面。我可能看起来它正在工作。它不起作用,它只是看起来像它。在其他情况下也可能不起作用。