Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Virtual Inheritance necessary for Exceptions?

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.

like image 882
Tim Avatar asked May 03 '11 18:05

Tim


People also ask

When you should use virtual inheritance?

Virtual inheritance is used when we are dealing with multiple inheritance but want to prevent multiple instances of same class appearing in inheritance hierarchy. From above example we can see that “A” is inherited two times in D means an object of class “D” will contain two attributes of “a” (D::C::a and D::B::a).

Should we always use virtual inheritance if yes why if not why not?

The answer is definitely no. The base of an idiomatic answer can be the most fundamental idea of C++: you only pay for what you use. And if you don't need virtual inheritance, you should rather not pay for it. Virtual inheritance is almost never needed.

Why virtual classes are important in the case of multiple inheritance?

Virtual base classes offer a way to save space and avoid ambiguities in class hierarchies that use multiple inheritances. When a base class is specified as a virtual base, it can act as an indirect base more than once without duplication of its data members.

What is virtual inheritance What problem does this feature address?

Virtual inheritance solves the classic “Diamond Problem”. It ensures that the child class gets only a single instance of the common base class. In other words, the Snake class will have only one instance of the LivingThing class. The Animal and Reptile classes share this instance.


2 Answers

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.

like image 161
GManNickG Avatar answered Sep 30 '22 18:09

GManNickG


Yes if your exception classes involve multiple inheritance.

like image 39
kirakun Avatar answered Sep 30 '22 20:09

kirakun