Boost logo

Boost Users :

From: Daniel Krügler (dsp_at_[hidden])
Date: 2008-06-27 05:20:45

Khandelwal, Amit wrote:
> I am reading through the paper by B. Strousstrup on multiple inheritance and this is what is says.
> A class can have an arbitrary number of virtual base classes.
> One can cast from a derived class to a virtual base class, but not from a virtual base class to a derived
> class. The former involves following the virtual base pointer; the latter cannot be done given the information
> available at run time.

[Sorry for my late answer, yesterday I was out-of-office basically the
complete day.]

Correct, it cannot be done for the general case due to potential
ambiguity ("path-split"). But in can be done, if the dynamic_cast
mechanism follows a unique path.

> Storing a ''back-pointer'' to the enclosing object(s) is non-trivial in general and
> was considered unsuitable for C++ as was the alternative strategy of dynamically keeping track of the
> objects ''for which'' a given member function invocation operates. The uses of such a back-pointer mechanism
> did not seem to warrant the added implementation complexity, the extra space required in objects, and
> the added run-time cost of initialization.
> class Cloneable : public virtual CloneableBase { .. }
> As per B. Strousstrup we cannot do it. Am I missing something obvious?

It be done, but there are exceptions, where it cannot be done.
For example there is no problem in the quoted cases:

class A : public Cloneable<A> {}; // abstract base for B and C
class B : public A, public NaturallyCloneable<B> {};
class C : public A {
     virtual A* doClone() const {
             return new C;

The reason is because CloneableBase is an abstract class, so during the
doClone() call of the clone function in Cloneable you will invoke
doClone() of an even more derived class as Cloneable itself is.
The result of doClone() will be a CloneableBase* to this derived
object. The dynamic_cast attempty now to find this derived class and
in many cases this search will be successful, see e.g. this extended
example from [expr.dynamic.cast]/9:

class A { virtual void f() {} };
class B { virtual void g() {} };
class D : public virtual A, private B { };
class E : public D, public B { };
class F : public E, public D { };

int main() {
   F f;
   A* ap = &f; // succeeds: finds unique A
   D* dp = dynamic_cast<D*>(ap); //#1 fails: yields 0
                  // f has two D subobjects
   F* fp = dynamic_cast<F*>(ap); //#2
   E e;
   ap = &e;
   E* ep = dynamic_cast<E*>(ap); //#3

#1 fails, because via ap you can find two different D

#2 and #3 both succeed, because there is only *one*
object F that can be found and similar for the E object.

The rules for these cases are described in [expr.dynamic.cast]/8,
which handle the runtime check of dynamic_cast.

> I have also seen the following error - something expected ..
> cannot convert from base `CloneableBase' to derived type `A' via
> virtual base `CloneableBase

Please provide a concrete example, currently I do not see where this
should apply for the finally provided solution via dynamic_cast.

Greetings from Bremen,

Daniel Krügler

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at