2

通过非常量引用在try-block中抛出构建在堆栈上的对象,捕获并修改它,然后通过引用另一个catch块抛出它有什么问题吗?

下面是我所指内容的简短示例。

struct EC {
    EC(string msg) { what = msg; }
    string where;
    string what;

    void app(string& t) { where += t; }
    string get() { return what; }
};

try {
    try {
        try {
            EC error("Test");
            throw error;
        }
        catch (EC& e) {
            e.app("1");
            throw e;
        }
    }
    catch (EC& e) {
        e.app("2");
        throw e;
    }
}
catch (EC& e) {
     e.app("3");
     cout << e.where << endl;
     cout << e.get() << endl;
}

这是否可能导致 e.what 包含垃圾,但 e.where 保持完整?例如:
e.where is "123"
e.get() 返回大量垃圾数据,直到碰巧碰到一个空字节。

4

1 回答 1

8

没有“通过引用抛出”这样的东西。这简直是​​不可能的。没有语法。每次尝试“抛出引用”时,实际上都会抛出被引用对象的副本。不用说,没有尝试在您的代码中通过引用抛出。

可以通过引用(甚至是非常量)捕获先前抛出的异常,并通过它修改临时异常对象。它会起作用的。事实上,您可以重新抛出现在修改的现有异常对象,而不是创建一个对象。即你可以做

throw;

代替

throw e;

在您的 catch 子句中,仍然可以获得行为正确的代码,即原始对象(带有修改)将继续通过处理程序层次结构飞行。

但是,您的代码格式不正确

e.app("1"); 

调用(和其他调用app),因为参数是非常量引用。app将声明更改为

void app(const string& t) { where += t; }  // <- either this
void app(string t) { where += t; }         // <- or this

让它编译。

否则,您的代码应该可以正常工作。你不应该从中得到任何垃圾get()。如果你这样做了,那一定是你的编译器有问题,或者你的代码没有显示。

于 2010-02-16T17:19:15.533 回答