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-Thread: 103376,104df2b9b7a2f689 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!news.glorb.com!atl-c03.usenetserver.com!elnk-atl-nf1!newsfeed.earthlink.net!stamper.news.atl.earthlink.net!newsread2.news.atl.earthlink.net.POSTED!14bb18d8!not-for-mail Sender: mheaney@MHEANEYX200 Newsgroups: comp.lang.ada Subject: Re: Interfaces References: <8764xj9wzf.fsf@deneb.enyo.de> From: Matthew Heaney Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Fri, 20 May 2005 05:31:28 GMT NNTP-Posting-Host: 24.149.57.125 X-Complaints-To: abuse@earthlink.net X-Trace: newsread2.news.atl.earthlink.net 1116567088 24.149.57.125 (Thu, 19 May 2005 22:31:28 PDT) NNTP-Posting-Date: Thu, 19 May 2005 22:31:28 PDT Organization: EarthLink Inc. -- http://www.EarthLink.net Xref: g2news1.google.com comp.lang.ada:11097 Date: 2005-05-20T05:31:28+00:00 List-Id: Florian Weimer writes: > Suppose there are two interface types, J1 and J2, and the following > dispatching subprogramms: > > procedure Foo (Obj : J1); > procedure Foo (Obj : J2); This is no different from COM, for example: interface I1 : IUnknown { /* ... */ }; interface I2 : IUnknown { /* ... */ }; Now both I1 and I2 have QueryInterface, AddRef, etc. > T implements both J1 and J2, and provides a body for > > procedure Foo (Obj : T); This is no different from a class that inherits from both I1 and I2: class C : public I1, public I2 { public: HRESULT QueryInterface(...); //... }; The operation QueryInterface is inherited from both I1 and I2. > As far as I understand the Ada 200x spec, this subprogram declaration > overrides both versions of Foo, such that > > Foo ((J1 (T_Obj)); > Foo ((J2 (T_Obj)); > > invoke the same subprogram. Is this correct? This is no different from saying: void f(C& obj) { const HRESULT hr = obj.QueryInterface(...); } > I don't think this is a desirable approach because it makes interfaces > a strictly non-modular concept, and might force library designers to > add unique prefixes to interface subprogram names. In the example above, both I1::QueryInterface and I2::QueryInterface do exactly the same thing, so the same subprogram should be called. If you have a true name clash (meaning that two separate interfaces have the same name for an operation that does completly different things), then all you have to do is declare one of the interfaces as a nested class (in Ada-speak, that would be a "multiple views idiom"): class C : public I1 { public: void foo(); //I1::foo() class C2 : public I2 { void foo(); }; C2 m_obj2; }; Now you can say: void f(C& obj) { obj.foo(); //I1 obj.m_obj2.foo(); //I2 } You don't have to have unique prefixes or anything for your interface types, since the outer class serves in effect as the prefix. Note that COM hides the nesting behind QueryInterface. That's more or less how the multiple views idiom works in Ada: type T is limited private; function Get_I1 (O : access T) return I1_Access; function Get_I2 (O : access T) return I2_Access; So instead of: Foo ((J1 (T_Obj)); Foo ((J2 (T_Obj)); You would say: Foo (Get_I1 (T_Obj'Access).all); Foo (Get_I2 (T_Obj'Access).all); Being able to inherit from multiple interface types is mostly a syntactic convenience. Nested classes work in COM, and the multiple views idiom works in Ada95. Calling Foo as in your example is a statement that I1::Foo and I2::Foo do the same thing. (Like QueryInterface, or AddRef, etc.) If you want to overload the name Foo across interface types, then fine, just revert to the multiple views idiom for one or both of the interface types. -Matt