views:

65

answers:

1

I have never seen a class used as virtual and nonvirtual base (i.e. if some class is intended to be an ancestor then we usually know in advance about type of inheritance - virtual or nonvirtual).

So I suppose that there is an error-prone freedom in c++ to specialize "virtual" inheritance in base class list. It should be better to specify as "virtual" the base class itself

Or maybe I'm wrong?

If no, can anybody describe some technics to prevent accidental nonvirtual inheritance for such a "virtual" class?

Or there are some perspectives in upcoming c++ standards?

(Sorry if duplicate)


Some examples

1) ReferenceCounted class as base for all classes that some reference-count-based smartpointer can point to. We need to prevent duplicates of this base instances (and reference counters). There are no reasons to use this class as nonvirtual base, except of optimization.

2) A hierarchy of interfaces and corresponding hierarchy of implementations (interfaces hierarchy must be "virtual" in this case)

// interfaces:

struct BaseIface{
  void virtual func()=0;
};

struct DerivedIface: public virtual BaseIface{
  void some_another_func()=0;
}


// implementations

class BaseImpl: public virtual BaseIface{
  void virtual func(){....};
}

class DerivedImpl: public BaseImpl, public virtual DerivedIface{
  void some_another_func(){...};
}

I suspect that in many cases nonvirtual inheritance is not a conceptual need, it used only to reduce virtual inheritance overhead (and sometimes for an ability to static_cast<> to drived :)

Note, that Java used ONLY virtual (in terms of c++) inheritance for interfaces, and I don't know any complains that this language lacks "nonvirtual" (it is esentially less expressive language than c++ but this "feature" is not it's main fault :).

+1  A: 

There's not really much way you could do this in the base class (nor would you really want to). It's perfectly reasonable to use a base class for both virtual and non-virtual inheritance.

What you'd really like would be to specify the virtual inheritance in the most derived class, where currently has to be specified in the intermediate classes. Unfortunately, I don't see much way around that -- even though virtual inheritance becomes necessary (primarily) when a class derives from two (or more) other classes that each have a common base, the virtual inheritance really governs how those two other classes are compiled, so if you (only) specified it in the most derived class, you'd end up with something almost like export, where you might need to go back and re-compile those intermediate classes based on the most derived class specifying virtual inheritance (and have some way to store the intermediate classes compiled both ways since it might be used either or both ways).

Jerry Coffin
You just describe problems with "lazy" virtual inheritance and the solution isto use "nonlazy" one, i.e. to define "virtual" for most base (not most derived) classHowever, I probably should better explain my intention, so I've added some examples to my question.