From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,7a180be12347b9d3 X-Google-Attributes: gid103376,public X-Google-Thread: 1108a1,7a180be12347b9d3 X-Google-Attributes: gid1108a1,public X-Google-ArrivalTime: 2002-02-11 06:47:37 PST Path: archiver1.google.com!news1.google.com!sn-xit-02!sn-post-02!sn-post-01!supernews.com!corp.supernews.com!not-for-mail From: "Matthew Heaney" Newsgroups: comp.lang.ada,comp.object Subject: Re: Merits of re-dispatching [LONG] Date: Fri, 8 Feb 2002 19:41:01 -0500 Organization: Posted via Supernews, http://www.supernews.com Message-ID: References: <3c62524f.93369796@News.CIS.DFN.DE> <1013191766.895310@master.nyc.kbcfp.com> X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4807.1700 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300 X-Complaints-To: newsabuse@supernews.com Xref: archiver1.google.com comp.lang.ada:19862 comp.object:34064 Date: 2002-02-08T19:41:01-05:00 List-Id: "Hyman Rosen" wrote in message news:1013191766.895310@master.nyc.kbcfp.com... > I don't understand the argument you are making. The problem seems to me that > when you make a dispatching call in the destructor (automatically in C++ or by > request in Ada), C++ will take you to a safe function, whereas Ada will take > you to a function which can manipulate already finalized submembers. First of all, the programmer may depend on the derived class member function being called, so saying that it's "safe" to call the base class member function instead of the derived class member function is specious. Yes, we all know why the language behaves this way, and we agree that the language should behave this way, but that doesn't help the programmer who mistakenly believes otherwise. Even if the base class member function is called, his class is still broken. Second of all, you can't make a strict one-for-one comparison of the languages wrt destruction (C++) and finalization (Ada95). In C++, the derived part has been destroyed, and who knows what mayhem would ensue if a member function were called after that had happened. So of course C++ does the right thing by not calling the derived class member function. However, in Ada95, the Finalize operation of the parent is called while the Finalize operation of the derived type is still executing (per the idiom, it's the last thing you do before returning). So the derived part of the type is still there. To call a dispatching operation in the parent's Finalize amounts to a contract violation (a precondition wasn't satisfied by the caller -- here, the parent type). This is bad, but it's no different then any other contract violation. And who knows? You could easily implement the Finalize operation using dispatching calls -- it's up to the designer of the class. For example: package P is type T is new Finalization.Limited_Controlled with null record; procedure Op1 (O : in out T); procedure Op2 (O : in out T); procedure Finalize (O : in out T); end P; package body P is procedure Finalize (O : in out T) is begin Op1 (T'Class (O)); --dispatch Op2 (T'Class (O)); end; end P; package P.C is type NT is new T with null record; procedure Op1 (O : in out NT); procedure Op2 (O : in out NT); procedure Finalize (O : in out NT); end P.C: package body P.C is procedure Finalize (O : in out NT) is begin Finalize (T (O)); --call parent's version end; end P.C; Here the derived type implements Finalize by calling the parent's Finalize, who then calls the derived type back. This is perfectly legal, and perfectly safe. It's also idiosyncratic, but that's another matter.