More object model questions
David Abrahams
david.abrahams at rcn.com
Thu Jan 10 20:44:20 CET 2002
----- Original Message -----
From: "John H. Spicer" <jhs at edg.com>
>
> I'm afraid that after all that I don't have anything very interesting to
> say except that it sounds like a good reason for extended RTTI. It also
> sounds like we need a variant of dynamic_cast that can take a typeid
> as the destination type.
Now /that/ sounds promising!
It knows something about the static type of the source so it can find vtbls,
and the typeid can provide the rest of what's needed. Will you propose an
extension?
> I also think I agree with your original sentiment that you can't do what
> you wanted to do with the dcast entries, although I'm still not sure I
> understanding things well enough to be sure.
No, I think you are :(
> I hope it wasn't too much of a waste of your time explaining all this to
me!
Not too much; I've been learning a lot as I think about the problem. Man,
it's complicated. I'm not sure how heroic to be. This is example is from
5.2.7 in the standard:
[Example:
class A { virtual void f(); };
class B { virtual void g(); };
class D : public virtual A, private B {};
void g()
{
D d;
B* bp = (B*)&d; // cast needed to break protection
A* ap = &d; // public derivation, no cast needed
D& dr = dynamic_cast<D&>(*bp); // fails
ap = dynamic_cast<A*>(bp); // fails
bp = dynamic_cast<B*>(ap); // fails
ap = dynamic_cast<A*>(&d); // succeeds
bp = dynamic_cast<B*>(&d); // fails
}
class E : public D, public B {};
class F : public E, public D {};
void h()
{
F f;
A* ap2 = &f; // succeeds: finds unique A
D* dp = dynamic_cast<D*>(ap2); // fails: yields 0
// f has two D sub-objects
E* ep = (E*)ap2; // ill-formed:
// cast from virtual base
E* ep1 = dynamic_cast<E*>(ap2); // succeeds
}
The graph looks like this, where A is a virtual base:
A B
^ :\
+---+...: \
| \
bp --> D |
ap --> |\ |
| +-+---+
| |
| E
| |
+-+-+
|
ap2 --> F
If the user has represented the entire graph to us, we /can/ find a D* given
ap2: We detect that the most-derived type is F, so we
dynamic_cast<void*>(ap2). Then we can cast up to E and from there,
unambiguously to D. The other D is completely unreachable.
More information about the Cplusplus-sig
mailing list