Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!sunic!tut!tukki!sakkinen From: sakkinen@tukki.jyu.fi (Markku Sakkinen) Newsgroups: comp.lang.c++ Subject: Re: Protected members Message-ID: <2218@tukki.jyu.fi> Date: 30 Nov 89 08:26:20 GMT References: <1989Nov28.122925.20804@newcastle.ac.uk> <1111@mit-amt.MEDIA.MIT.EDU> Reply-To: sakkinen@jytko.jyu.fi (Markku Sakkinen) SAKKINEN@FINJYU.bitnet (alternative) Organization: University of Jyvaskyla, Finland Lines: 85 In article lindsay@stobhill.newcastle.ac.uk (Lindsay F. Marshall) writes: -I have an application that worked under the 1.2 rules but wil not -compile under 2.0. This seems to be to a considerable tightening of -the rules for protected members. What I am not sure is whether or not -it is correct!! The situation - - class A - { - protected:: - A(); - ~A(); - void* data; - }; - - class B : public A - { - public: - B(); - ~B(); - A* next; - }; - -So B is derived from and A and an instance of class B can access the -field data without problems. However, if the class B uses an instance -of class A inside one of its members, for example: - - - B::~B() - { - while (next != this) - { - delete next; - } - } - -The compiler will not permit this access saying that the destructor is -protected. The same thing happens if one tries to access next->data. -Is this correct or is the compiler being too strict? If it's correct -is there any point in having a protected, non-virtual destructor - it -might as well be private. - -This happens with both C++ 2.0 and g++ 1.36.1 . In article <1111@mit-amt.MEDIA.MIT.EDU> peter@media-lab.media.mit.edu (Peter Schroeder) writes: >[...] >This is correct. As a member of B, A* is just some class and can only be >accessed as allowed by the original class definition. > >If we defined a class D which looks exactly like class A and then replaced >the occurence of A* in B by D* it would be clear that we cannot expect to >be able to access D's desctructor. > >I stumbled over this a few times, since 1.2.1 of cfront did not seem to >enforce it, but I can now see that it makes sense to forbid this. > >Hope this helps. This problem was discussed here some 2 months (?) ago. I and someone else argued that the old principle is logical insofar as the unit of encapsulation in C++ is a class (and not an object as in Smalltalk, say). Of course there are arguments in favour of the new principle, too. However, with regard to the much-advertised "stability" of C++ the _change_ was unfortunate. This restriction is explicitly written in section 11.5 of the new C++ Reference Manual (thank you, Bjarne, for sending me a copy). To solve the problem in the original question, it seems necessary to declare B also a friend of A. This means that the definition of A must be changed when such derived classes are added, which may not always be convenient. One possible trick to circumvent this comes to mind, but I cannot deduce from the Ref.Man. whether it is legal in current C++: Define a dummy class AA and declare it a friend class of A. Then, since we now have multiple inheritance, make AA another public base class of B. If classes derived from a friend class of A remain friends of A, this should work, otherwise not. Markku Sakkinen Department of Computer Science University of Jyvaskyla (a's with umlauts) Seminaarinkatu 15 SF-40100 Jyvaskyla (umlauts again) Finland