为什么C++标准库不使用虚拟继承进行异常?

Mar*_*tin 5 c++ inheritance exception

C++标准库定义了std :: runtime_error,类似于从std :: exception继承,但继承不是虚拟的.这使异常层次结构的扩展变得复杂.例如,以下代码存在问题.

class sql_exception : public virtual std::exception {...};
class sql_disconnected : public virtual std::runtime_error, public virtual sql_exception {...};
void do_something() {
  throw sql_disconnected();
}
void call_something() {
  try {
     do_something();
  } catch (const std::exception& e) {
  }
}
Run Code Online (Sandbox Code Playgroud)

std :: exception没有被捕获,因为它应该是恕我直言.这可以通过各种(不必要的复杂[IMHO])方式来解决.

我相信标准应该允许这种行为,因为它不是我必须假设有一个很好的理由,除了"这是标准,因为它是标准".

我知道虚拟继承会产生一些成本,但与堆栈展开和其他异常处理的成本相比,AFAIK可以忽略不计.

Q1:标准库出于什么技术原因实现了这种行为?

问题2:是否考虑了扩展层次结构的问题,如果是的话,标准对该主题的评价是什么?标准是否阻止它或建议遵循?

Rem*_*eau 1

sql_disconnected对我来说,从同一事物派生std::runtime_error但又不sql_exception从同一事物派生是没有意义的。恕我直言,任何 SQL 错误都应该被视为运行时错误。 std::runtime_error派生自std::exception,因此您不需要首先创建钻石层次结构,因此您不需要使用虚拟继承来解决该问题。标准 STL 异常都不使用虚拟继承,您的自定义异常也不应该使用虚拟继承。

class sql_exception : public std::runtime_error {...};
class sql_disconnected : public sql_exception {...};

void do_something() {
  throw sql_disconnected();
}

void call_something() {
  try {
     do_something();
  }
  catch (const std::exception& e) {
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是问题的答案。最多你描述为什么问题附带的例子不是最好的例子。问题是关于 C++ 标准库,而不是关于用于说明它的示例代码。 (5认同)