c – 异常切片 – 这是由于生成的拷贝构造函数?
作者:互联网
我刚刚在代码中修复了一个非常微妙的错误,这是由异常切片造成的,我现在想确保我完全理解发生了什么.
这是我们的基本异常类,派生类和相关函数:
class Exception
{
public:
// construction
Exception(int code, const char* format="", ...);
virtual ~Exception(void);
<snip - get/set routines and print function>
protected:
private:
int mCode; // thrower sets this
char mMessage[Exception::MessageLen]; // thrower says this FIXME: use String
};
class Derived : public Exception {
public:
Derived (const char* throwerSays) : Exception(1, throwerSays) {};
};
void innercall {
<do stuff>
throw Derived("Bad things happened!");
}
void outercall {
try {
innercall();
}
catch(Exception& e)
{
printf("Exception seen here! %s %d\n", __FILE__, __LINE__);
throw e;
}
}
该错误当然是外部调用最终会抛出异常,而不是派生.我的错误是由于调用堆栈中的高位尝试捕获Derived失败而导致的.
现在,我只想确保理解 – 我相信在’throw e’行,使用默认的复制构造函数创建一个新的Exception对象.这是真的发生了什么?
如果是这样,我是否可以锁定将被抛出的对象的复制构造函数?我真的更喜欢这种情况不会再次发生,我们的代码没有理由复制Exception对象(我知道).
请不要评论我们有自己的异常层次结构这一事实.这是一个我正在努力纠正的旧设计(我正在取得良好的进展.我已经摆脱了本土的字符串类,以及许多本土容器.)
更新:要明确的是,在我提出问题之前,我已经修复了错误(通过将’throw e’更改为’throw’).我只是想确认发生了什么.
解决方法:
抛出一个对象时,实际上是在抛出一个对象的副本,而不是原始对象的副本.想一想 – 原始对象在堆栈中,但堆栈正在展开并失效.
我相信这是标准的一部分,但我没有副本可供参考.
catch块中抛出的异常类型是catch的基本类型,而不是抛出的对象的类型.解决这个问题的方法是扔掉;而不是扔e;这将抛出原始捕获的异常.
标签:object-slicing,c,exception 来源: https://codeday.me/bug/20190930/1836554.html