虚拟继承是否需要异常? [英] Is Virtual Inheritance necessary for Exceptions?

查看:134
本文介绍了虚拟继承是否需要异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我理解使用多重继承时需要虚拟继承 - 它解决了可怕的钻石问题。



但是,如果我不使用多重继承,该怎么办? 是否需要虚拟继承?



我似乎回想起来,对异常很重要(抛出一个派生类,catch通过基类引用)。但是虚拟析构函数不应该是足够的吗?



我曾经尝试搜索我曾经看到的参考页面,但我似乎找不到

解决方案

你可能在想这个 Boost.Exception指南,我将在这里复制完整性:





在异常类型中使用虚拟继承



异常类型在从其他异常类型派生时应使用虚拟继承。这个见解是由于安德鲁·科尼格所致。使用虚拟继承可以防止异常处理程序中的歧义问题:

  #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<< 哎呦! <<的std :: ENDL; }
}

上面的程序输出哎呀!因为转换为std :: exception是不明确的。



在异常处理的上下文中,虚拟继承引入的开销总是可以忽略不计。请注意,虚拟基础是由最传导类型的构造函数(传递给throw语句的类型,在异常情况下)直接初始化。但是,通常,当boost :: 异常,因为它使异常类型成为平凡的结构,没有成员(没有任何初始化)。将异常类型视为简单的语义标签


I understand the need for virtual inheritance when using multiple inheritance -- it solves the Dreaded Diamond Problem.

But what if I'm not using multiple inheritance? Is there a need for virtual inheritance at all?

I seem to recall hearing that it was important for exceptions (throw a derived class, catch by base class reference). But shouldn't virtual destructors be sufficient for that?

I've tried searching for the reference page I once saw on this, but I can't seem to find it.

解决方案

You're probably thinking about this Boost.Exception guideline, which I'll copy here for completeness:


Using Virtual Inheritance in Exception Types

Exception types should use virtual inheritance when deriving from other exception types. This insight is due to Andrew Koenig. Using virtual inheritance prevents ambiguity problems in the exception handler:

#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; }
    }

The program above outputs "whoops!" because the conversion to std::exception is ambiguous.

The overhead introduced by virtual inheritance is always negligible in the context of exception handling. Note that virtual bases are initialized directly by the constructor of the most-derived-type (the type passed to the throw statement, in case of exceptions.) However, typically this detail is of no concern when boost::exception is used, because it enables exception types to be trivial structs with no members (there's nothing to initialize.) See Exception Types as Simple Semantic Tags.

这篇关于虚拟继承是否需要异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆