C++ 通过引用抛出非常量临时变量
通过非常量引用在try块中抛出堆栈上构造的对象,捕捉并修改它,然后通过引用将其抛出到另一个catch块,是否存在任何问题 下面是我指的一个简短的例子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 {
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否。为什么在这个上下文中还要提到引用?