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,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.129.84.2 with SMTP id i2mr9697193ywb.148.1495405732415; Sun, 21 May 2017 15:28:52 -0700 (PDT) X-Received: by 10.157.14.91 with SMTP id n27mr422515otd.8.1495405732368; Sun, 21 May 2017 15:28:52 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.glorb.com!l39no771925qtb.0!news-out.google.com!m134ni5210itb.0!nntp.google.com!67no1244876itx.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Sun, 21 May 2017 15:28:52 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=173.71.201.205; posting-account=QF6XPQoAAABce2NyPxxDAaKdAkN6RgAf NNTP-Posting-Host: 173.71.201.205 References: <4a47e4cd-829c-4451-abf1-82cf60b67706@googlegroups.com> <9cdf04e6-123e-4bd9-b466-77aad00d61bb@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <1cb79ede-c4ec-4a37-b6c7-4ca45bc76cf1@googlegroups.com> Subject: Re: Preventing private procedure visibility being made public through extension From: Jere Injection-Date: Sun, 21 May 2017 22:28:52 +0000 Content-Type: text/plain; charset="UTF-8" Xref: news.eternal-september.org comp.lang.ada:46846 Date: 2017-05-21T15:28:52-07:00 List-Id: On Sunday, May 21, 2017 at 5:07:13 PM UTC-4, Dmitry A. Kazakov wrote: > On 2017-05-21 22:06, Jere wrote: > > On Sunday, May 21, 2017 at 4:44:27 AM UTC-4, Dmitry A. Kazakov wrote: > >> On 2017-05-21 00:51, Jere wrote: > >>> On Saturday, May 20, 2017 at 4:32:07 PM UTC-4, Dmitry A. Kazakov wrote: > >>>> On 2017-05-20 19:33, Jere wrote: > >>> I do know that C++ supports hiding of functions by making them private > >>> in the extending class. > >> > >> No. That is not possible in C++ either. A public method cannot be made > >> private. > >> > >> In general from the OO point of view, a method cannot be removed because > >> it is a property of the class and not of an individual type. It is the > >> contract of the class to have a method Foo. All instances of the class > >> must have this method. If they don't they are not instances of. Period. > >> > >> [To support method disallowing the language must support ad-hoc > >> superclasses, so that one could split an original class into parts to > >> chip the undesired operation away from one part and put the new type in > >> that part instead of the whole original class.] > >> > > The language supports making them private in the context of the > > extending classes. Take for example: > > > > class Base{ > > public: > > class Base_Param{}; > > > > void Something(Base_Param Obj){} > > Something is not a method here. If you make it a method [= Ada's > primitive operation]: > > virtual void Something (Base_Param Obj); > > then your code will stop compiling. Sort of. If you change the code to: class Base{ public: class Base_Param{}; virtual void Something(Base_Param Obj){} }; class Derived : public Base { private: void Something(Base_Param Obj){ /*Do something Safe here*/ } }; class MoreDerived : public Derived{}; and then void run_test(){ Base::Base_Param b; MoreDerived m; m.Something(b); } It will correctly fail as Something() is private in the MoreDerived context. (ERROR= 'virtual void Derived::Something(Base::Base_Param)' is private). However, void run_test(){ Base::Base_Param b; MoreDerived m; Base &r = m; Base *ptr = &m; //Dispatching works correctly r.Something(b); ptr->Something(b); } will happily compile. When you privatize a virtual method, it needs a body, but it will still be private when used as a Derived and MoreDerived type. You are right that in Ada terms, Something is not a primitive operation. C++ doesn't have this requirement though (I'm guessing they are not equivalent to primitive operations because of this), so a non virtual method is still considered a method (in c++) and can be overriden, it just can't dispatch (only virtual functions dispatch in C++). Sorry if I sound combative, I don't mean to be. I think I just am used to different definitions of some terms. Either way, I get that there is no way to do it in Ada. I really do appreciate the responses. > An Ada example corresponding to yours is this: > > package Base is > type Base_Type is null record; > procedure Something (X : in out Base_Type); > end Base; > > package Derived is > type Derived_Type is new Base_Type; > procedure Something (X : in out Derived_Type) is abstract; > end Derived; > > X : Base_Type; > Y : Derived_Type; > begin > Something (X); > Something (Y); -- This won't compile > Yes, I agree, but I don't have control over the base type, so I am stuck with a tagged type. > > You're right, they are not proper constructors. I haven't found > > anything in Ada yet that gives me that. At best they are > > initializers. > > > >>> I really don't like doing this. I don't like using > >>> access types for one. It's also doesn't feel like > >>> a very clean way because you have to do something > >>> out of the ordinary just to use the class like it was > >>> meant to be. > >> > >> Aggregation + delegation is a decent thing. > >> > >> If you used anonymous access you would reduce dangers of pointers to zero. > >> > > Definitely. I am also worried about someone copying the access > > value and holding onto it past the lifetime of the object. > > Anonymous access types are difficult to copy. Accessibility rules were > made to prevent any unsafe copying. So you will have to break them by > doing X.all'Unchecked_Access. > If Get_Access is returning not null access Base.Base_Type, what prevents someone from doing: type My_Base_Access is access all Base.Base_Type; Ptr : My_Base_Access; and then Ptr := Some_Variable.Get_Access; I know you said anonymous access types are difficult to copy, but the small example I tried in GNAT GPL 2016 allows such a copy. Is this a compiler bug? If not, I think I misunderstood.