C++ 通过引用抛出非常量临时变量

C++ 通过引用抛出非常量临时变量,c++,exception,undefined-behavior,C++,Exception,Undefined Behavior,通过非常量引用在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块中抛出堆栈上构造的对象,捕捉并修改它,然后通过引用将其抛出到另一个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;
}
struct-EC{
EC(字符串msg){what=msg;}
字符串在哪里;
串什么;
void app(string&t){where+=t;}
字符串get(){返回什么;}
};
试一试{
试一试{
试一试{
EC错误(“测试”);
投掷误差;
}
渔获物(EC&e){
e、 附录(“1”);
投掷e;
}
}
渔获物(EC&e){
e、 附录(“2”);
投掷e;
}
}
渔获物(EC&e){
e、 附录(“3”);
cout没有“通过引用抛出”这样的事情。这是不可能的。没有语法。每次尝试“抛出引用”时,实际上会抛出引用对象的副本。不用说,代码中没有尝试通过引用抛出

可以通过引用捕获以前抛出的异常(即使是非常量异常),并通过它修改临时异常对象。这将起作用。事实上,您可以重新抛出现在已修改的现有异常对象,而不是创建新的异常对象。也就是说,您可以这样做

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

void-app(const-string&t){where+=t;}//无法复制。也不会使用app()中的非常量引用进行编译。在任何情况下,您都不会抛出引用,而是抛出一个副本。这不是为了编译。代码只是说明了我所指的内容。我问过这样的事情是否会导致e.get()包含垃圾数据,如果它编译并工作的话就不可能了如果需要复制构造函数,则返回垃圾邮件。可能值得一提的是,您应该通过引用捕获以避免对象滑动如果我有
MyClass obj
,然后
throw&obj
,那么会发生什么情况?这是在抛出引用吗?@CătălinaSîrbu否。为什么在这个上下文中还要提到引用?