其他分享
首页 > 其他分享> > c-通过引用抛出非常量临时对象

c-通过引用抛出非常量临时对象

作者:互联网

通过非常量引用将构造在堆栈上的对象扔到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"); 

调用(以及对应用程序的其他调用),因为该参数是非常量引用.将应用程序声明更改为

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

以便编译.

否则,您的代码应该可以正常工作.您不应该从get()中获取任何垃圾.如果这样做,则可能是编译器或未显示的代码有问题.

标签:c,undefined-behavior,exception
来源: https://codeday.me/bug/20191009/1879654.html