TITLE: pros and cons of using virtual inheritance (Newsgroups: comp.lang.c++.moderated, 22 May 97) KANZE: James Kanze |> > In practice, one is always on the safe side by declaring a the base |> > class virtual. It is really the exceptional case where you want two |> > instances, and generally, you can do it anyway. If Base1 declares A |> > virtual, it will only share it with other classes that declare it |> > virtual as well; if Base2 does not declare it virtual, you get two |> > instances. |> > |> > There are really only two reasons why people don't make all inheritance |> > virtual, systematically: |> > |> > 1. For various reasons, MI has gotten a bad name, and many people simply |> > suppose that no reasonably programmer will use it. I admit that I find |> > it difficult to understand this reasoning; if MI didn't exist, I would |> > have to simulate it one way or another (in a statically typed language |> > like C++, of course). |> > |> > 2. Performance. Navigating a class hierarchy which used virtual bases |> > is significantly slower than navigating one that doesn't, and classes |> > using virtual inheritance are often significantly bigger than those that |> > don't. This largely depends on the compiler, of course. I have one |> > case (based on real code in our application) where the CFront based |> > compiler we use in production work uses *10* times more memory than a |> > more modern compiler; all of the extra memory is used in the |> > implementation of virtual base classes. Eliminating virtual inheritance |> > (not an option in this case) would mean being able to handle |> > significantly larger data sets (and probably running faster, due to less |> > page faulting). HOPPS: Kevin J. Hopps (kjhopps@mmm.com) |> Another reason not to make all inheritance virtual is that it really |> complicates things for the users and derivers of the class. With |> virtual inheritance it means that the most derived class has to invoke |> all the base class constructors. Getting assignment operators and copy |> constructors right can be a real headache too. KANZE: Good point. I forgot about that one, and it could be a pain. Of course, when I'm actually using virtual inheritance, I will try and ensure that the virtual bases all have default constructors, so that the final user doesn't have to worry about it. In practice, another poster suggested rigorously distinguishing between inheritance of interface (public virtual) and inheritance of implementation (private). If this is done, there should be no problem, since interface classes are normally abstract, and data-less, and thus do not need a constructor (with arguments). ZEISEL: zeisel@vai.co.at (Helmut Zeisel) |> > |> Now my questions: [...snip...] |> > |> 4) Are experienced programmers able to easily tell |> > |> whether a base class should be virtual or not? KANZE: [...snip...] |> > I consider the |> > author of the class which gave me problems an experienced programmer, |> > and decidedly more competent than the average. He still didn't realize |> > that someone would want to use his base class in an MI hierarchy. So |> > the answer is definitly no. (I know that one data point is not |> > significant, but my impression is that the problem is general. To begin |> > with, I find no mention of it in such major references as Scott Meyers. |> > And just how fundamental it was didn't occur to me until I was actually |> > bitten by the problem.) HOPPS: |> Meyers does mention it in _Effective C++_. He discusses the time and |> space penalties you mention above, and then says, "In view of these |> considerations, it would seem that effective class design in the |> presence of MI calls for clairvoyance on the part of library designers. |> Seeing as how run-of-the-mill common sense is an increasingly rare |> commodity these days, you would be rather ill-advised to rely too |> heavily on a language feature that calls for designers to be not only |> anticipatory of future needs, but downright prophetic." |> |> As I mentioned above, because of the problems that virtual inheritance |> creates for users and derivers, not to mention the time and space |> penalties, I do not use virtual inheritance unless I know of a need for |> it. KANZE: Well, this has been my practice too, until now. But the basic motivation is that the compilers I am required to use do such a bad job of it. With more modern compilers, I think that I would probably systematically declare inheritance from dataless classes virtual. This still doesn't solve all of the problems, though.