通过非常量引用将构造在堆栈上的对象扔到try块中,捕获它并对其进行修改,然后通过引用另一个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。“123”在哪里
e.get()返回大量垃圾数据,直到碰巧碰到一个空字节为止。

最佳答案

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

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

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()中获取任何垃圾。如果这样做,则可能是编译器或未显示的代码有问题。

09-10 06:34
查看更多