简体   繁体   English

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

[英]Why does the C++ standard library not use virtual inheritance for exceptions?

The C++ standard library defines std::runtime_error and similar to inherit from std::exception, but the inheritance is not virtual. C ++标准库定义了std :: runtime_error,类似于从std :: exception继承,但继承不是虚拟的。 This complicates the extension of the exception hierarchy. 这使异常层次结构的扩展变得复杂。 For example the following code has problems. 例如,以下代码存在问题。

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) {
  }
}

std::exception is being not caught, as IMHO it should be. std :: exception没有被捕获,因为它应该是恕我直言。 This can be worked around in various (needlessly complicated [IMHO]) ways. 这可以通过各种(不必要的复杂[IMHO])方式来解决。

I believe the standard should permit this behavior, and since it doesn't I have to assume there is a good reason, other than "this is the standard because it is the standard". 我相信标准应该允许这种行为,因为它不是我必须假设有一个很好的理由,除了“这是标准,因为它是标准”。

I am aware that there is some cost associated with virtual inheritance, but AFAIK it's negligible compared to the cost of stack unwinding and the rest of the exception handling. 我知道虚拟继承会产生一些成本,但与堆栈展开和其他异常处理的成本相比,AFAIK可以忽略不计。

Q1: For what technical reason did the standard library implement this behavior? Q1:标准库出于什么技术原因实现了这种行为?

Q2: Was the problem of extending the hierarchy considered, and if so what does the standard say about the topic? 问题2:是否考虑了扩展层次结构的问题,如果是的话,标准对该主题的评价是什么? Does the standard discourage it or have a recommendation to follow? 标准是否阻止它或建议遵循?

It does not make sense to me to derive sql_disconnected from std::runtime_error but not also derive sql_exception from the same. 它没有意义,我得出sql_disconnectedstd::runtime_error但也从中sql_exception来自同一个。 IMHO any SQL error should be treated as a runtime error. 恕我直言,任何SQL错误都应被视为运行时错误。 std::runtime_error derives from std::exception , so you don't need to create a diamond hierarchy in the first place, and thus you don't need to use virtual inheritance to solve that problem. std::runtime_error派生自std::exception ,因此您不需要首先创建菱形层次结构,因此您不需要使用虚拟继承来解决该问题。 None of the standard STL exceptions use virtual inheritance, neither should your custom exceptions. 标准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) {
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM