
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
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