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