异常是否需要虚拟继承?
Is Virtual Inheritance necessary for Exceptions?
我理解在使用多重继承时需要虚拟继承——它解决了可怕的菱形问题。
但是如果我没有使用多重继承呢?是否需要虚拟继承?
我似乎记得听说过它对异常很重要(抛出派生类,通过基类引用捕获)。但是,虚析构函数不就足够了吗?
我试着搜索我曾经在这个上面看到的参考页面,但是我似乎找不到它。
您可能正在考虑这个Boost。异常指南,为了完整起见,我将复制到这里:
在异常类型中使用虚拟继承
当从其他异常类型派生时,异常类型应该使用虚拟继承。这是Andrew Koenig的见解。使用虚拟继承可以防止异常处理程序中的歧义问题:
#include <iostream>
struct my_exc1 : std::exception { char const* what() const throw(); };
struct my_exc2 : std::exception { char const* what() const throw(); };
struct your_exc3 : my_exc1, my_exc2 {};
int
main()
{
try { throw your_exc3(); }
catch(std::exception const& e) {}
catch(...) { std::cout << "whoops!" << std::endl; }
}
以上程序输出"whoops!"因为转换到std::exception是有歧义的。
在异常处理上下文中,虚拟继承带来的开销总是可以忽略不计的。请注意,虚基是由派生最多的类型的构造函数直接初始化的(在发生异常的情况下,传递给throw语句的类型)。然而,当使用boost::exception时,通常不关心这个细节,因为它使异常类型成为没有成员的平凡结构(没有什么可初始化的)。参见异常类型作为简单语义标记
如果你的异常类涉及多重继承,
虚拟继承的唯一代价是虚函数表,这不是很大的代价。使用虚拟继承意味着以后人们从各种事物继承后,双钻石问题不会意外地出现。这只是意味着你的类将成为一个很好的基类。
不需要,除非是为了解决钻石问题。你一定是在胡思乱想!
我理解在使用多重继承时需要虚拟继承——它解决了可怕的钻石问题。
但是如果我没有使用多重继承呢?
问题(主要是反问句):你怎么知道MI永远不会被使用?
答案:你不可能知道。(直到你证明你知道。)
我似乎记得听说过它对异常很重要(抛出派生类,通过基类引用捕获)。但是,虚析构函数不就足够了吗?
问题(修辞):为什么这里需要虚析构函数?
答案:不是。
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 大小虚拟继承中的派生类
- 删除C++继承中虚拟类成员的代码重复
- 重写虚拟函数和继承
- C++ 多级虚拟继承编译问题
- 如何正确获得虚拟继承?
- 编译时继承类中的隐式虚拟与显式虚拟
- 钻石继承虚拟成员铸造与指针
- CPP 继承虚拟方法解析顺序
- 关于C 接口(纯虚拟类)/多重继承/虚拟继承的设计Qustion
- 继承虚拟类C 的派生类
- 多个继承/虚拟函数
- 不能从具有虚拟继承(C++虚拟继承)的类派生
- C++多重继承+虚拟函数(-歧义)=怪异行为(也是函数指针)
- 为什么我不能继承虚拟基的构造函数?
- C++继承虚拟函数崩溃
- c++多重继承/虚拟继承
- 派生类的成员函数是否从基类继承虚拟性?
- 继承虚拟函数的类的boost::optional失败的原因
- c++继承虚拟函数