Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!usc!apple!Apple.COM!lsr From: lsr@Apple.COM (Larry Rosenstein) Newsgroups: comp.sys.mac.programmer Subject: Re: HandleObjects in C++ Message-ID: <5186@internal.Apple.COM> Date: 14 Nov 89 18:36:25 GMT Sender: usenet@Apple.COM Organization: Objects-R-Us, Apple Computer, Inc. Lines: 56 References:<934@swbatl.UUCP> <5162@internal.Apple.COM> <16875@dartvax.Dartmouth.EDU> <3158@husc6.harvard.edu> <16898@dartvax.Dartmouth.EDU> In article <16898@dartvax.Dartmouth.EDU> erics@eleazar.dartmouth.edu (Eric Schlegel) writes: > I'm perfectly happy to accept that, but I am curious.. is this is _permanent_ > incompatibility, or might it be fixed someday? Now that Rich has reminded me of why HandleObjects don't support multiple inheritance, I can answer more intelligently. (Thanks, Rich.) It is unlikely that this will change. MPW C++ uses the standard runtime implementation from AT&T's CFront product. I don't think there's any motivation for AT&T to change the implementation; I don't know whether Apple would want to make such an extensive modification to CFront. There's a paper (by Bjarne Stroustrup, I think) on the implementation. The problem for handle objects is that the C++ runtime implementation must move the pointer to the object before it calls a method. Normally you allocate and object on the heap and return pointer to it. Then you pass that pointer as a hidden parameter to each method call. With multiple inheritance, calling a method involves adding an offset to that pointer and passing the result as the hidden parameter. With a handle-based object, there's no way to pass a handle into the middle of the object. The only alternative I can think of is to use doubly-indirect pointers to objects (e.g., TMyObject **anObj). You can overload operator new with something like: (NOTE: I haven't tried this to see if it works, so be careful.) typedef enum {NewHandle} OperatorNewFlag; void* operator new(size_t objSize, OperatorNewFlag) { return (void*)NewHandle(objSize); } Then you would use it like: TMyObject **anObj = (TMyObject**) new(NewHandle) TMyObject(...); This is using the feature of C++ that lets you pass added parameters to operator new. In this case, we only care about the type of the parameter, and not its actual value. The statement above will call the overloaded operator new and allocate a handle. You have to remember this and coerce the result to the proper type. Once you have allocated the object in this way, then you can use it as a regular C++ object (e.g., *anObj -> Method(...)). You have to realize that this is using a dereferenced handle with all the cautions that apply in that case. Larry Rosenstein, Apple Computer, Inc. Object Specialist Internet: lsr@Apple.com UUCP: {nsc, sun}!apple!lsr AppleLink: Rosenstein1