Topic: downcast virtual base [for persistent objects,interprocess communication]


Author: lichtman@KOTW0002.mch.sni.de (Manfred Lichtmannegger)
Date: 3 May 1994 07:05:34 GMT
Raw View
First a sketch(!) of the overall structure of my system:

                      NamedClass
                     /virtual   \virtual
RefBase ----> PersistentRoot  IndependentObject
 | virtual         | virtual         | virtual
Ref<P>  - - >      P                 B
 |                 |                 |
Ref<Q>  - - >      Q                 D

I have four root classes which are only inherited virtual to
avoid ambiguities:

- PersistentRoot inherits a framework to make its derived classes
  persistent in a (relational) database.

- RefBase is a smart pointer which hides database accesses by
  dereferencing operator ->

- IndependentObject for sending objects in a machine independent
  form to other processes by encode and decode

- NamedClass to provide run time type information to use a
  class manager to allocate a derived object if a reference
  in the database or in a message of a base class points to a
  object of a derived object.

If I have a class which is both independent and persistent or
when I have multiple inheritance from persistent or independent
classes I get a diamond shaped inheritance DAG. Therefore I use
them as virtual base classes.

My compilers and the ARM say: don`t cast down a pointer of a
virtual base! But thats what I want.

Persistent objects are cached in an ObjectPool and aRefBase
remembers the address of its object after the first access.
I planned to use PersistentRoot* both in RefBase and in the
ObjectPool. It would be enough for methods like makePersistent
or markModified. The operator-> of Ref<P> would down cast it to
P* , which is now illegal.

It should be possible to convert between PersistentRoot* and P*
(saved as void* in RefBase) by virtual methods:

The pure virtual method void* getThis() of PersistentObject would
be implemented by

     void* P::getThis() { return (void*)this; }

and the pure virtual method PersistentObject* getPersistentObject()
of RefBase would be implemented by

  PersistentObject* Ref<T>::getPersistentObject()
  { return (PersistentObject*)(T*)myAddress; }

A greater problem is raised by the decodeing a D object instead
of a B object. Using run time type information I can allocate a
D by calling NamedClass::allocateObjectOfClass(ClassId). But this
class method can no longer return an IndependentObject* as a down
cast to B* would be illegal. It can only return a void*. But how
to cast a void* which is a D* to a B* which differ by a certain
offset?

Well an operation similar to

 void* cast(void* toCast,ClassId fromClass,ClassId targetClass) (*)

or by allocateObjectOfClass(ClassId ofClass,ClassId asClass) can do
the work. To avoid O(n*n) cast operators for pairwise upcast along
an inheritance path of length n, I would use the n-1 upcasts between
class and immediate base class to recursively upcast the hierarchy
till the target class is reached.

As these solutions to avoid down casts of virtual base classes
seems to be not really elegant I am asking for better solutions.
How can I simulate down casts of virtual base classes in the second
situation?

The very special initialization of the virtual base classes by the
most derived object i.e. the complete object itself seems to be
no real restriction as my root.

Hoping for good ideas Manfred

(*) I had some trouble with my compiler with the function template
    template <class targetClass> void cast(void*,sourceClass,T*&)

--

email: Manfred.Lichtmannegger@mch.sni.de
NERV: lenhardt.muc@sni.de (mark with li)

at the moment SNI BU BA NM 212 at Mch P/K room 92812, Rosenheimerstr. 116,
============= 81669 Muenchen Tel: 49-(0)89/4144-7723  Fax: 49-(0)89/4144-7720

Siemens Nixdorf Informationssysteme AG, SU AP 45 Raum 2712, Carl-Wery-Str. 22,
81730 Muenchen, Tel: 49-(0)89/636-45778  Fax: 49-(0)89/636-42504





Author: rmartin@rcmcon.com (Robert Martin)
Date: Fri, 6 May 1994 15:58:10 GMT
Raw View
lichtman@KOTW0002.mch.sni.de (Manfred Lichtmannegger) writes:

>My compilers and the ARM say: don`t cast down a pointer of a
>virtual base! But thats what I want.

This has changed.  If you have a compiler that supports true RTTI,
then you can use dynamic_cast to cast down from a virtual base.



--
Robert Martin       | Design Consulting   | Training courses offered:
Object Mentor Assoc.| rmartin@rcmcon.com  |   Object Oriented Analysis
2080 Cranbrook Rd.  | Tel: (708) 918-1004 |   Object Oriented Design
Green Oaks IL 60048 | Fax: (708) 918-1023 |   C++