Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!sdd.hp.com!wuarchive!uunet!zephyr.ens.tek.com!uw-beaver!milton!sumax!polari!rwing!seaeast!sunbrk!Usenet From: Doug.Orleans@sunbrk.FidoNet.Org (Doug Orleans) Newsgroups: comp.lang.c++ Subject: Casting downward Message-ID: <675518012.11@sunbrk.FidoNet> Date: 28 May 91 01:33:04 GMT Sender: Usenet@sunbrk.FidoNet.Org Lines: 73 Recently I began my first major C++ programming project. I am using Turbo C++ 1.0 on an XT clone. Turbo C++ comes with a fairly extensive class heirarchy, so I decided to use that as a base. I ran up against a major problem, however, when I tried to use multiple inheritance, and I came up with two solutions: one is a kludge, and the other involves a change in the language definition. My problem was this: there is a class Object which lies at the root of the heirarchy. One branch of the tree is the Container branch, which has classes such as Container, Collection, and Array. Another branch is the Sortable branch, which has classes of objects which can be sorted, such as String. I wanted to create a class which was a Sortable Array, so I inherited it from both classes. As the heirarchy is now, Container and Sortable have Object as non-virtual base classes. Thus my new class, SortableArray, has two Objects inside it. This is a problem, because the generic operators such as << and == are defined to operate on Objects, but a SortableArray cannot be implicitly cast to an Object. Rather than explicitly cast a SortableArray to an Array or a Sortable every time I want to use it, I decided to make Object a virtual base class of Container and Sortable. This caused another problem, because you cannot cast downwards from a virtual base class to a derived class. The main place this caused a problem was in the virtual function isEqual, which is a pure virtual function in Object. (This is what the operator == calls.) The function isEqual takes an Object reference as its argument. Thus my SortableArray class defines isEqual(Object &O), in which O is cast to a SortableArray so that it can be compared to *this. But an Object reference cannot be cast down to a SortableArray reference. My kludgey solution to this was to define a pure virtual function in Object called me. In every non-abstract class defined from Object, me returns a void pointer to this, i.e. (void *)this. Since any pointer can be cast to a void pointer, this is legal. Then in SortableArray's isEqual function, to cast Object &O to a SortableArray reference, I call O's me function, and cast that: SortableArray &S = *(SortableArray *)O.me() Since a void pointer may be cast to any other pointer, this is legal. This seems to work, although I have some other bugs which may or may not have anything to do with this. My idea to change the language to remedy this problem is to allow overloaded virtual functions. This is best described with an example: class Base { virtual int f(Base &); } class Derived : public Base { virtual int f(Derived &); } Base B; Derived D; In this example, D.f(B) will call B::f, D.f(D) will call D::f, and B.f(B) will call B::f, as it is now; but B.f(D) will call D::f, rather than B::f. Will this work? Is this feasible? Is there some other situation where you would prefer to have it the way it is now? Can you suggest a better way to solve my problem? Please send me email, and I will post a summary of the advice given. Doug Orleans dougo@soda.berkeley.edu * Origin: Seaeast - Fidonet<->Usenet Gateway - sunbrk (1:343/15.0)