其他分享
首页 > 其他分享> > c – 异常切片 – 这是由于生成的拷贝构造函数?

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